By user6127082


2017-05-23 11:28:20 8 Comments

I'm currently building a single page application using reactjs. I read that many of the reasons for not using localStorage is because of XSS vulnerabilities. Since React escapes all user input, would it now be safe to use localStorage?

8 comments

@Kidali Kevin 2019-11-25 08:00:43

It is safe to store your token in localStorage as long as you encrypt it. Below is a compressed code snippet showing one of many ways you can do it.

    import SimpleCrypto from 'simple-crypto-js';

    const saveToken = (token = '') => {
          const encryptInit = new SimpleCrypto('PRIVATE_KEY_STORED_IN_ENV_FILE');
          const encryptedToken = encryptInit.encrypt(token);

          localStorage.setItem('token', encryptedToken);
     }

Then, before using your token decrypt it using PRIVATE_KEY_STORED_IN_ENV_FILE

@Kidali Kevin 2019-12-11 16:38:39

@HassanAlthaf you are missing the point here, there will never be a 100% secure proof app, It’s just that, you’re reducing the attack surface and at least env file will not be published on github directly. Also, the bundled code will be obfuscated and mangled, making it hard for the attackers to find them.

@Hassan Althaf 2019-12-12 03:25:59

Private key is not supposed to be exposed. You would compromise the entire API.

@Kidali Kevin 2019-12-13 06:43:45

From my experience If you did things intelligently and correctly, your private key won't be exposed in your production build, if so, screenshot to support this or even a url.

@Alex Lyalka 2017-06-01 23:05:53

Basically it's OK to store your JWT in your localStorage.

And I think this is a good way. If we are talking about XSS, XSS using CDN, it's also a potential risk of getting your client's login/pass as well. Storing data in local storage will prevent CSRF attacks at least.

You need to be aware of both and choose what you want. Both attacks it's not all you are need to be aware of, just remember: YOUR ENTIRE APP IS ONLY AS SECURE AS THE LEAST SECURE POINT OF YOUR APP.

Once again storing is OK, be vulnerable to XSS, CSRF,... isn't

@Alejandro Cavazos 2017-11-06 17:55:57

This is why it is secure to do the following: - Store the JWT in a cookie so that it can't be retrieved from XSS - Store a CSRF token in localStorage so it can't be retrieved from CSRF

@Carl Leth 2018-04-30 20:53:00

You bring up a good point: if your site runs a malicious script, it's game over anyway. They can just bind keydown events to inputs of type password and steal your user's authentication information that way (which is much, much worse than stealing a JWT auth token). Storing JWTs in localStorage does little to increase the already immense possible damage from XSS.

@HenokG 2019-10-19 19:45:47

A way to look at this is to consider the level of risk or harm.

Are you building an app with no users, POC/MVP? Are you a startup who needs to get to market and test your app quickly? If yes, I would probably just implement the simplest solution and maintain focus on finding product-market-fit. Use localStorage as its often easier to implement.

Are you building a v2 of an app with many daily active users or an app that people/businesses are heavily dependent on. Would getting hacked mean little or no room for recovery? If so, I would take a long hard look at your dependencies and consider storing token information in an http-only cookie.

Using both localStorage and cookie/session storage have their own pros and cons.

As stated by first answer: If your application has an XSS vulnerability, neither will protect your user. Since most modern applications have a dozen or more different dependencies, it becomes increasingly difficult to guarantee that one of your application's dependencies is not XSS vulnerable.

If your application does have an XSS vulnerability and a hacker has been able to exploit it, the hacker will be able to perform actions on behalf of your user. The hacker can perform GET/POST requests by retrieving token from localStorage or can perform POST requests if token is stored in a http-only cookie.

The only down-side of the storing your token in local storage is the hacker will be able to read your token.

@SILENT 2019-04-16 21:24:29

Isn't neither localStorage or httpOnly cookie acceptable? In regards to a compromised 3rd party library, the only solution I know of that will reduce / prevent sensitive information from being stolen would be enforced Subresource Integrity.

Subresource Integrity (SRI) is a security feature that enables browsers to verify that resources they fetch (for example, from a CDN) are delivered without unexpected manipulation. It works by allowing you to provide a cryptographic hash that a fetched resource must match.

As long as the compromised 3rd party library is active on your website, a keylogger can start collecting info like username, password, and whatever else you input into the site.

An httpOnly cookie will prevent access from another computer but will do nothing to prevent the hacker from manipulating the user's computer.

@Mauricio Cortazar 2018-04-21 00:50:26

I know this is an old question but according what @mikejones1477 said, modern front end libraries and frameworks escape the text giving you protection against XSS. The reason why cookies are not a secure method using credentials is that cookies doesn't prevent CSRF when localStorage does (also remember that cookies are accessible by javascript too, so XSS isn't the big problem here), this answer resume why.

The reason storing an authentication token in local storage and manually adding it to each request protects against CSRF is that key word: manual. Since the browser is not automatically sending that auth token, if I visit evil.com and it manages to send a POST http://example.com/delete-my-account, it will not be able to send my authn token, so the request is ignored.

Of course httpOnly is the holy grail but you can't access from reactjs or any js framework beside you still have CSRF vulnerability. My recommendation would be localstorage or if you want to use cookies make sure implemeting some solution to your CSRF problem like django does.

Regarding with the CDN's make sure you're not using some weird CDN, for example CDN like google or bootstrap provide, are maintained by the community and doesn't contain malicious code, if you are not sure, you're free to review.

@miphe 2019-07-05 13:22:00

Not sure why you would say you're still vulnerable to CSRF while using cookies. Using a cookie with the flags HttpOnly SameSite=strict and secure, will keep the info you set in the cookies safe. Then against XSS, you simply make sure your JavaScript isn't aware of any authentication related data, like tokens and passwords (meaning, don't store them in Web Storage) - if you import a malicious script, that script will not have access to sensitive data. Yes, you will not have access to the token through JS either, but that really shouldn't be a problem.

@Mauricio Cortazar 2019-07-06 19:00:28

@miphe that's what i said. But the OP is asking for a way to access from javascript. Here i'm just explaining what is the best way to store a token accessible from js.

@Stephen L 2017-05-26 04:26:01

It is not safe if you use CDN's:

Malicious JavaScript can be embedded on the page, and Web Storage is compromised. These types of XSS attacks can get everyone’s Web Storage that visits your site, without their knowledge. This is probably why a bunch of organizations advise not to store anything of value or trust any information in web storage. This includes session identifiers and tokens.

via stormpath

Any script you require from the outside could potentially be compromised and could grab any JWTS from your client's storage and send personal data back to the attacker's server.

@user6127082 2017-05-26 06:40:38

If I don't plan on using cdns will it be safe then?

@Vlad 2018-12-29 00:11:49

The author of the article never made a distinction between XSS on sites served via a CDN or directly from a central server. Wouldn't your explanation here also apply generally, not just for CDNs?

@Ivan 2017-05-28 19:23:40

Localstorage is designed to be accessible by javascript, so it doesn't provide any XSS protection. As mentioned in other answers, there is a bunch of possible ways to do an XSS attack, from which localstorage is not protected by default.

However, cookies have security flags which protect from XSS and CSRF attacks. HttpOnly flag prevents client side javascript from accessing the cookie, Secure flag only allows the browser to transfer the cookie through ssl, and SameSite flag ensures that the cookie is sent only to the origin. Although I just checked and SameSite is currently supported only in Opera and Chrome, so to protect from CSRF it's better to use other strategies. For example, sending an encrypted token in another cookie with some public user data.

So cookies are a more secure choice for storing authentication data.

@Alex Lyalka 2017-06-01 22:49:33

cant get: how HttpOnly can protect you from CSRF ?

@Ivan 2017-06-02 00:07:54

@AlexLyalka Didn't mean to say that HttpOnly prevents from CSRF, rather than all cookie flags together can protect from XSS and CSRF. SameSite provides some protection, preventing the cookies from being sent to a site different from origin. Although I just checked and support for that flag is very low. It's also possible to avoid CSRF with a separate encrypted token with some user identification, which is checked on server.

@Borja Alvarez 2019-02-14 20:22:04

Well, if someone can execute code in your web, cant he simply make a post to ur web in the name of your user? Ok, he cant get your http only cookies, but he can make calls using those cookies, so I still cant see the point

@avejidah 2019-08-05 21:17:21

@BorjaAlverez There's a big difference. Yes, via XSS someone could make requests on behalf of logged-in user, but compromising a token is worse. For example: the token may provide access to APIs that the client application doesn't use; the token may have other information about the user (email address, profile, and grants); the token could be used in replay attacks against your application; the token could be passed as an id_token_hint to an OIDC auth server; the token provides an attacker information about the cipher that was used to sign it; etc.

@Kaloyan Kosev 2017-05-26 19:49:49

In most of the modern single page applications, we indeed have to store the token somewhere on the client side (most common use case - to keep the user logged in after a page refresh).

There are a total of 2 options available: Web Storage (session storage, local storage) and a client side cookie. Both options are widely used, but this doesn't mean they are very secure.

Tom Abbott summarizes well the JWT sessionStorage and localStorage security:

Web Storage (localStorage/sessionStorage) is accessible through JavaScript on the same domain. This means that any JavaScript running on your site will have access to web storage, and because of this can be vulnerable to cross-site scripting (XSS) attacks. XSS, in a nutshell, is a type of vulnerability where an attacker can inject JavaScript that will run on your page. Basic XSS attacks attempt to inject JavaScript through form inputs, where the attacker puts <script>alert('You are Hacked');</script> into a form to see if it is run by the browser and can be viewed by other users.

To prevent XSS, the common response is to escape and encode all untrusted data. React (mostly) does that for you! Here's a great discussion about how much XSS vulnerability protection is React responsible for.

But that doesn't cover all possible vulnerabilities! Another potential threat is the usage of JavaScript hosted on CDNs or outside infrastructure.

Here's Tom again:

Modern web apps include 3rd party JavaScript libraries for A/B testing, funnel/market analysis, and ads. We use package managers like Bower to import other peoples’ code into our apps.

What if only one of the scripts you use is compromised? Malicious JavaScript can be embedded on the page, and Web Storage is compromised. These types of XSS attacks can get everyone’s Web Storage that visits your site, without their knowledge. This is probably why a bunch of organizations advise not to store anything of value or trust any information in web storage. This includes session identifiers and tokens.

Therefore, my conclusion is that as a storage mechanism, Web Storage does not enforce any secure standards during transfer. Whoever reads Web Storage and uses it must do their due diligence to ensure they always send the JWT over HTTPS and never HTTP.

@SuperLemon 2017-09-29 11:43:29

So if I'm understanding you correctly, you recommend cookies? Just to make sure. Thanks!

@Kaloyan Kosev 2017-09-29 19:07:19

Yes. I recommend cookies because of the additional security they provide, and the simplicity of protecting against CSRF with modern web frameworks. Web Storage (localStorage/sessionStorage) is vulnerable to XSS, has a larger attack surface area, and can impact all application users on a successful attack.

@mikejones1477 2017-11-07 18:21:41

I think you have these mixed up? Modern web frameworks have strong built in defenses for XSS. But not so much for xsrf. The best defense for xsrf is to avoid using cookies completely. Local storage is sandboxed to a specific domain, which means an attackers domain can't access it. Web frameworks defend against xss by automatically encoding and sanatizing user input. See angular.io/guide/security

@spechter 2018-05-15 06:24:07

If "you recommend cookies [instead]", then, can I recommend you say that somewhere in the answer? Rather than just in the comments?

@Sergiu Sandrean 2018-10-01 10:25:32

@mikejones1477: As the answer says "Modern web apps include 3rd party JavaScript libraries" which means you can never be 100% sure that you're defended against XSS attacks, or which means you can't be sure that your localStorage can't be accessed by an attacker. The best way to stay secure is to store your token in the cookie and implement a CSRF protection (which most backend frameworks offer nowadays).

@Borja Alvarez 2019-01-14 09:44:10

I'm here a bit late, just reading these topics now and I'm confused about one thing, a lot of people talk about u're protected with an http only cookie if you are comprimised with Xss, but, if you have xss the atacker does not need to steal you anything, he can simple make a post from the page to impersonate you using that cookie (even if he cant steal it). Am I missing something???

@Merv 2019-02-13 19:39:51

@Borja Alvarez .. Yes you are that making of a post is protected by usage of CSRF protection. Without it yes you are right.

@Paul Griffin 2019-04-19 16:19:11

@Merv With or without CSRF protection, if you fall victim to XSS the attacker can send a post request. If they can run their code on your site they have no need to send the request cross site. I'm all in favour of storing JWT in a HttpOnly secure flag cookie, because why not? But really, if an XSS attack gets through the attacker can do what they like, send post requests, steal passwords, etc. The fact they can't read the JWT is small comfort.

@Merv 2019-04-23 14:17:50

@BorjaAlvarez I agree if an attacker can run their code on your site then they would be able to do harm. But what they will not be able to do is read your JWT token. So they will always need your site up and running to do what they want to do. So in a way they will be at the mercy of your site. But if they are able to read your JWT token then its a party because you (server, company) won't ever know that its not the user who is sending requests because they are sending a valid JWT-token. And yes CSRF protection protect you only when your site is XSS safe.

@avejidah 2019-08-05 21:07:25

You're not stuck with "a total of 2 options." If you must store tokens in your user agent (which you shouldn't be doing), then store them in memory without persistence. That's Auth0's recommendation (auth0.com/docs/security/store-tokens#if-no-backend-is-prese‌​nt) OWASP specifically advises against storing tokens in web storage: cheatsheetseries.owasp.org/cheatsheets/…

@Evans M. 2020-02-22 08:58:00

If you store your token in memory what happens if the user refreshes the page? Do you ask them to login again? Also what about open one of the pages in a new tab?

Related Questions

Sponsored Content

27 Answered Questions

[SOLVED] Invalidating JSON Web Tokens

22 Answered Questions

[SOLVED] Storing Objects in HTML5 localStorage

14 Answered Questions

[SOLVED] How to find the size of localStorage

8 Answered Questions

13 Answered Questions

[SOLVED] What is the max size of localStorage values?

11 Answered Questions

[SOLVED] Clearing localStorage in javascript?

2 Answered Questions

[SOLVED] localstorage do note update JWT Reactjs

5 Answered Questions

[SOLVED] How persistent is localStorage?

Sponsored Content