overhide.io blog
— free open-sourced "for gratis" and "in-app-purchase" (IAP) based authorizations in dollars and cryptos
— back-end code optional and front-end only OK... write code once but support many coins
— make the fusion of "logins" and "in-app-purchases" (IAPs) as banal and unliable as possible
27 Mar 2019
by Jakub Ner

When authoring a service or application targeted for a de-compilable user-agent such as a browser, it may be tempting to put all of your application’s business-logic in a single code base–one that runs wholly in browsers–and leverage ledgers.js for authentication and authorization. However, you must be cognizant that such application source code is in the clear, modifiable, and checks for authorization grants can be easily circumvented.

Browser code minifiers such as uglify.js obfuscate code and make it less comprehensible, but that only slows down bad actors who intend to copy the code and modify it.

This is an issue when your business-logic has code flows conditional on authorization tiers.

ledgers.js

The overhide ledgers.js library helps a user authenticate, review authorizations, and top-up payments as necessary. The library–for its intended purposes–has its place in the login UX portion of overhide’s ledger-based authorization flow.

Figure 1: Ledger-based authorization flow.

The library can be used in a browser without any caveats for bad actors modifying the source code–as the login UX exposes ledger tallies for information purposes only–to enhance user experience . It allows signing for identity and popping-up widgets for transacting, but these are all user provided aspects. The bad actor–being the user here–doesn’t gain anything by hacking away at the login UX.

The Problem

With reference to figure 1 above, authorization occurs down in the business-logic (task in red). When the business-logic runs wholly in a browser, the wrong thing to do would be to check signature legitimacy and fetch ledger tallies right then and there, in browser code, directly using remuneration API or ledgers.js.

Consider the sample code of such business-logic:

var uri = ...; /* https://ledger.overhide.io/v1, https://ethereum.overhide.io, or ... */
var fee = ...;
var isAuthorizedForExtraGoodies = false;

...

fetch(`${uri}/get-transactions/${from}/${to}?tally-only=true${since}`)
  .then(res => res.json())
  .then(res => {
    if (res.tally >= fee) {
      isAuthorizedForExtraGoodies = true;
    }
  })
  .catch(e => {
    ...
  });

...

if (isAuthorizedForExtraGoodies) {
  
  ...

  // functionality paid for

  ...

}

When a tally of transactions comes back (fetch->then), if it meets some fee expectation, the boolean that allows code flows with extra goodies is set to true (isAuthorizedForExtraGoodies = true)

There is nothing stopping a bad actor from flipping that boolean using developer tools right in the browser: gaining access to extra goodies for free.

The Solution

The solution is to create dependencies on a back-end; some code outside of the browser, perhaps cloud functions (see demo). Dependencies that will re-validate authorization and process/furnish mission-critical state/data back to the application. You need to make back-end calls as part of the application’s business-logic.

To drive the point home, ledgers.js will authenticate and help negotiate authorizations browser-side–but that’s solely for the benefit of user experience. The library will help establish some public auth data in the form of a user-address, message and signature. These non-secret auth details must be provided to the back-end so the back-end can re-validate relevant authorization grants.

Hence, in the back-end, in the critical-paths of business-logic we want gated with authorizations, we must re-validate authorizations by checking a public ledger and confirming a match for the provided user-address, message and signature.

We never provide any private-keys, secrets, or passwords to the back-end: this is not needed, with the user-address and signature the back-end can validate authentication and query public ledgers to check authorizations.

To do these back-end verifications we leverage the same very simple API that ledgers.js uses: the remuneration API. It’s a very minimal back-end authorization check.

At the end of the day a bad actor is not a legitimate user and majority of your efforts should likely focus on supporting legitimate users. Keep your fees fair and your updates frequent.