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

On the jwt.io inroduction page, it sites HTML5 Security - OWASP Cheat Sheet Series 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!

2 Likes

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 auth0-spa-js/Auth0Client.ts at 0e390f96b4fe200bcf2bdca4f7ff5705a439f7bf · auth0/auth0-spa-js · GitHub

Here is how this method is used in a sample SPA application calling a backend API auth0-javascript-samples/app.js at master · auth0-samples/auth0-javascript-samples · GitHub

Hope that helps clarify.
Few more references

  1. Token Storage
  2. Authenticate Single-Page Apps With Cookies
  3. Auth0 JavaScript SDK Quickstarts: Login
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?

2 Likes

I’m not familiar with cache.ts but it looks like an in-memory object/array that is simply storing objects. This is fast and great for a single HTML page but when navigating to a new page or new tab, won’t you lose this context?