• caglararli@hotmail.com
  • 05386281520

Storing encrypted tokens in LocalStorage

Çağlar Arlı      -    9 Views

Storing encrypted tokens in LocalStorage

I am building a JavaScript application that will run in a web browser but also as a pseudo-native mobile application via Apache Cordova. It communicates via API to a separate backend service.

The app requires that the user be prompted for some kind of identifying information whenever it is launched, but for ease of use this need not be their full username and password. Password entry in particular (and especially on mobile devices) will be too cumbersome to make this feasible. Therefore, we are considering a once-off login procedure where the full credentials are supplied, followed by a “setup” step where the user creates a PIN for future access. This could, in future, be extended to allow a fingerprint/face scan to also “unlock” the app on supported devices.

We are also hoping to avoid the use of cookies. Doing so subsequently avoids CSRF concerns but also, support for cookies in Cordova applications appears to be either non-existent or at least unreliable.

My initial thoughts on implementation are:

  • The user submits a valid username/password combination to a login/ endpoint of the API and receives an “ID token” in response.
  • During the “setup” phase, the PIN chosen by the user is used to encrypt the ID token.
  • The encrypted ID token is stored in LocalStorage.
  • A secondary request is made to an authorise/ endpoint of the API, including the plaintext ID token. Assuming the token validates, a second token is issued to the app.
  • This second token is what is used in all subsequent requests to the API to prove the user is trusted, has a relatively short expiry, and is not stored in any persistent manner by the application.
  • Upon returning to the app at a later date, the user need only provide their chosen PIN.
  • It can be used to decrypt the stored ID token, which is then used in the authorise/ request to generate and return a new short-lived session token.

The internet abounds with articles advising against the use of LocalStorage for anything sensitive, due to its exposure in the event of XSS attacks. The threat is that a token in LocalStorage could be stolen when the same token in an httpOnly cookie could not. It is worth noting that in both cases, a malicious script running within the app could successfully issue fraudulent requests to the backend API.

I believe the XSS threat of the ID token being stolen is mitigated by it being encrypted under the user’s PIN, and neither the decrypted value nor the PIN itself being stored or used beyond the authorise/ request.

The session token is also vulnerable to being stolen by XSS. It is only stored in memory, but is obviously still accessible to JavaScript and thus to a malicious script. These tokens would be given short expiry times to mitigate this threat. Not to mention we would do our best to harden against XSS in the first place.

I think the above sounds like a secure way to implement our requirements, but I am no security expert. Am I missing any obvious weaknesses here? Does this actually sound secure?