In the context of a web application... should sensitive tokens, such as those used for sessions, authentication and/or authorization, be stored in localStorage or an HTTPOnly cookie; or are they both acceptable approaches in different circumstances?
For the purposes of this question, assume that the token in question, whatever form it might take, could be leveraged to impersonate the user / hijack their session if it were disclosed to an adversary.
Background
My personal understanding/belief has always been that HTTPOnly
cookies are the optimal security choice in these situations, due to the risks associated with cross-site scripting. OWASP's HTML5 cheat sheet recommends the same.
Pro HTTPOnly cookies:
- A successful cross-site scripting attack cannot access the token.
- Malicious browser extensions cannot access the token.
- Exploiting the token is more difficult for the attacker, who has to make XMLHttpRequests through the victim's browser (when the token will be automatically attached to the request).
Pro localStorage / sessionStorage:
- Cross-site request forgery attacks are entirely prevented.
To me, both XSS and CSRF attacks are complex to protect against and would benefit from multiple layers of security controls as a result. I.e. I see experienced development teams still produce applications with the occasional XSS and/or CSRF bug - protecting against these issues universally and at scale can be challenging.
localStorage appears to completely resolve CSRF, but leaves the token accessible to malicious JavaScript in the event of an XSS bug. HTTPonly cookies partially mitigate XSS but introduce CSRF as a new attack vector, which has to be protected via its own controls. The impact of an XSS attack is potentially higher than CSRF.
HTTPOnly
Cookie. CSRF and XSS are both different and require separate mitigation technique for each. XSS always defeats CSRF, even protected ones. While CSRF doesn't have anything to do with XSS. It's also worth noting that we now haveSameSite
cookies which prevents CSRF altogether if done correctly.