7

I am trying to understand the security implications of storing jwt in local storage (prone to xss) vs cookie (prone to csrf). I would like to understand the security implications if I store the jwt token in my app state in the frontend, like in a redux store.

EDIT:

I have tried to find out more about storing tokens. It seems all the articles and answers actually start the discussion after establishing that there are 2 ways to do that, cookies or browser storage. Like this relevant question: Where to store JWT in browser? How to protect against CSRF? Like these posts: https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage https://auth0.com/docs/security/store-tokens

I understand the point of most of these, but I am trying to explicitly discuss the option of global variable.

gaurav5430
  • 12,934
  • 6
  • 54
  • 111
  • I get that there are a lot of answers discussing about local storage vs cookies, but could not find any which discusses global variable. It might be completely idiotic to do so and that is what I was trying to find out. – gaurav5430 Mar 01 '19 at 11:55
  • The duplicate question linked above does not discuss global variables. – gaurav5430 Mar 01 '19 at 11:56
  • @mplungjan I did try to google it and none of the links actually discussed a global variable. All of them are about cookie vs local storage. I am happy to update the question with this info if that means it can be opened for explanations/answers again. – gaurav5430 Mar 01 '19 at 11:59
  • Yes show what you investigated and your conclusions and why it is not a dupe of https://stackoverflow.com/questions/27067251/where-to-store-jwt-in-browser-how-to-protect-against-csrf – mplungjan Mar 01 '19 at 12:06

3 Answers3

6

If you store a JWT in a global variable, or any store available from the global context, it is exposed to all of the JS code on the same page. If you trust every other JS script of your page, and if you can guarantee that your page is not vulnerable to code injection attacks, then it's safe to store the JWT in a global variable.

If you can't guarantee that the JWT will be safe, don't use global variables, prefer using encapsulation like this:

(function() {
  // Retrieve the JWT from somewhere
  var jwt = "mockjwt";

  //All of the code that needs the JWT goes here
  console.log('Safe code:', jwt);

  
})();

// Evil code, either:
// - Injected through a vulnerability of your website (e.g: eval misuse,
//   WYSIWYG editor vulnerable to script tag injection, etc...)
// - Injected because your user got fooled by some "copy/paste this code in the F12 tab
//   of your browser, and you'll unlock a secret functionality"
// - Untrusted <script> tag that you added to your website

console.log('Evil code:', jwt);  //Fails because the JWT is scoped to the anonymous
                                 //function and is not accessible from anywhere outside
                                 //the function.
Guerric P
  • 30,447
  • 6
  • 48
  • 86
  • Great insight. Would storing it in a global variable also mean that the user would need a new token if they refresh the page? – gaurav5430 Mar 02 '19 at 04:06
  • Also, in this usage is it similar to local storage? as any injected code can also read local storage, great point about browser console, would it apply to local storage as well? – gaurav5430 Mar 02 '19 at 04:08
  • 1
    Of course, by doing this, the javascript context (thus the token) is lost on every page refresh. In terms of vulnerability to code injection, there is no better solution between global variables and local storage. Global variables can be dumped with code like `for(let key in window) { console.log(window[key]); }`.and local storage can be dumped with `localStorage` so none of the solutions provide obfuscation. – Guerric P Mar 04 '19 at 08:37
2

As per my understanding, storing JWT in browser local storage/cache is more about persisting token(user authorization) through browser sessions.

Ajay
  • 4,773
  • 3
  • 23
  • 36
0

If your website is vulnerable to a JS injection as Guerric P said, then the JWT would be affected.

But, what if... you combine PHP in order to random-gender JS variables and save the token there?

Something like:

krm480dmkm8w273mkmxw8283 = "xxxxxxxxx.xxxxxxxxx.xxxxxxxxxx"
wke9434mkdmkd3872kd294df = "xxxxxxxxx.xxxxxxxxx.xxxxxxxxxx"
eyru482nm91njm47mkdm99qq = "xxxxxxxxx.xxxxxxxxx.xxxxxxxxxx"

Well, on the one hand, you can't just get as easy the token, because instead of having always the same variable name, you have always a unique one, so you can't get it as easy.

On the other hand, maybe, a JS script that performs a search of variable content matching 3 dots would expose you, but... you make it harder for an attacker to expose your tokens.

I would like anyone to give more info if this method would be secure or not. Thanks.