Auth0 Home Blog Docs

Isn't storing a JWT in a non-httponly cookie just as insecure as local storage?

On the jwt.io inroduction page, it sites https://cheatsheetseries.owasp.org/cheatsheets/HTML5_Security_Cheat_Sheet.html#local-storage when explaining why we should not store our jwt in browser storage. That leaves cookies as our storage mechanism when using a browser. But it then goes on to recommend that we send the jwt in the Authorization header which would mean that the cookie cannot be HTTP-only since it must be read by the client-side JS in order to put the jwt in the request header. The whole point of using the cookie was to avoid letting malicious JS read the value from local storage, but if the cookie can be read by JS it seems like it is no better than local storage. The secure and same-site cookie flags also don’t benefit us in this case since we are just extracting the value and putting it in the request header.

I feel like I am missing something and would appreciate any clarification as to the recommended use of JWT between a browser client and api. Thanks!

1 Like

Hi @adampog77 Welcome to Auth0 community. Great first question.

If you look at our quickstarts they show how tokens are stored post authentication on client side, you will notice they are being stored in in-memory cache. For eg. our vanilla js quickstart uses our auth0-spa.js sdk and it has a method getTokensSilently https://github.com/auth0/auth0-spa-js/blob/0e390f96b4fe200bcf2bdca4f7ff5705a439f7bf/src/Auth0Client.ts#L291

Here is how this method is used in a sample SPA application calling a backend API https://github.com/auth0-samples/auth0-javascript-samples/blob/master/02-Calling-an-API/public/js/app.js#L76

Hope that helps clarify.
Few more references

  1. https://auth0.com/docs/security/store-tokens#don-t-store-tokens-in-local-storage
  2. https://auth0.com/docs/login/spa/authenticate-with-cookies
  3. https://auth0.com/docs/quickstart/spa/vanillajs
1 Like

Thanks for the info! I wasn’t aware of the in-memory cache. I’ll have to look into that some more.

1 Like

What protects this in-memory cache from having the same issues as the browser storage mechanisms? For example, wouldn’t that in-memory cache still be readable by malicious JS on the client?