I'm using JSON web tokens for authentication in my app. Since data is pulled from protected routes in the API, security tokens are stored in the frontend.

My question is this: Is using HTML's localStorage to store JWTs (nothing else) an unsafe option compared to cookies? I understand cookies have their own disadvantages, but I'm looking for the safest way available to store a JWT locally.

  • 2
    If you trust the cookie model your service could use htmlOnly cookies Session scoped containing the JWT – eckes May 5 '19 at 14:20
  • Talking about security cookies have some mechanisms, mainly HttpOnly (Which disable access through JavaScript) and Secure (which forces sending it only through HTTPS), unlike xStorage. But still, both have vulnerabilities, Cookies are vulnerable to CSRF, and xStorage are vulnerable to XSS, – Azteca Jun 4 '19 at 21:36

localStorage should never be used for storing any sensitive data; if you absolutely must use something other than cookies, use at least only sessionStorage instead, which is only available to that window/tab until the window is closed.

  • You cannot control the expiration time like you can do with cookies.

  • A single XSS vulnerability can be used to steal all the information from data inside localStorage, also it persists when you close the tab.

  • localStorage doesn't have any options to restrict the visibility of an object to a specific path like with the attribute path of HTTP Cookies. Cookies are ideal because you have much more control over them: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie You can specify a number of attributes/flags, like: Secure, HttpOnly, SameSite, HostOnly.

  • It wasn't designed as a secure storage mechanism, and it's implementation can vary from browser to browser.

  • There is no way to restrict script-access to information stored in localStorage, which is possible with the HttpOnly attribute for cookies.

  • Cookies are stored encrypted on the client computer, unlike data in local storage.

OWASP strongly advises to never use local storage for storing any sensitive information:

Any authentication your application requires can be bypassed by a user with local privileges to the machine on which the data is stored. Therefore, it's recommended not to store any sensitive information in local storage.

JWTs are highly sensitive data. Not only because they act as tokens for authentication, but they also very often contain sensitive data like email/username, roles, etc. only base64-encoded (although best practice is to avoid that). So they are often still to be considered sensitive data even when they are not valid anymore.

I recommend to read the corresponding section in OWASP's HTML5 Security Cheat Sheet: https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/HTML5_Security_Cheat_Sheet.md

An interesting read about the topic can be found at: https://dev.to/rdegges/please-stop-using-local-storage-1i04

| improve this answer | |

Using localStorage is no less safe than using cookies, with two exceptions:

  1. It's possible to set cookies as HTTPOnly, but then they'd be unusable from JavaScript, which in this case would defeat the purpose).
  2. There's no equivalent of a cookie's "path" for localStorage, but this would only matter if you're running untrusted code in the same origin anyway, which invalidates pretty much every security guarantee.

In fact, localStorage may even be safer, as it isn't sent to the server automatically with each request, which means there's no ambient authentication, and thus less risk of CSRF.

| improve this answer | |
  • 1
    "Using localStorage is no less safe than using cookies" This is wrong. I recommend to read the section "Local Storage" in OWASP's HTML5 Security Cheat Sheet: github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/… – Martin Fürholz Jun 4 '19 at 7:51
  • 1
    @MartinFürholz I added one exception from there into my answer ("path"). Everything else it warns about applies equally to cookies. – Joseph Sible-Reinstate Monica Jun 4 '19 at 13:07
  • I'm afraid that's wrong. I suggest you read it again. I have highlighted many points in my answer, I don't have the intention to fight with you. – Martin Fürholz Jun 4 '19 at 20:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.