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.
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.