Generally no. OWASP advises against storing session identifiers or other sensitive data in localStorage, because JavaScript can always read it and a single XSS bug can steal everything in it. Cookies with the HttpOnly flag reduce that risk, though they bring their own design needs.
Why localStorage is a risky place for secrets
localStorage and sessionStorage are readable by any script running on the page. That includes your code, your dependencies, a third party script tag, and anything an XSS flaw lets an attacker inject. OWASP's HTML5 Security Cheat Sheet puts it directly: a single XSS can steal all the data in these objects, and a single XSS can also load malicious data into them, so you should not treat their contents as trusted.
It also notes that it is appropriate to use local storage where access to the data does not assume authentication or authorization, and that there is no way to restrict an object to a path the way cookies can. Every object is shared within an origin.
What belongs where
| Data | localStorage or sessionStorage? | Reason |
|---|---|---|
| Theme, language, UI layout | Fine | No authority attached |
| Draft text a user is typing | Fine, with care | Low sensitivity, treat as untrusted on read |
| Session identifiers | No | Always readable by JavaScript |
| Access or refresh tokens | Avoid, weigh alternatives | One XSS reads them |
| Personal data | Avoid | Same reason, plus privacy duties |
OWASP also recommends sessionStorage over localStorage if persistence is not needed, since sessionStorage is available only to that window or tab until it closes. It narrows exposure but does not stop XSS.
Safer patterns to consider
- Let the server set the session in a cookie with HttpOnly, Secure and a SameSite value, so scripts cannot read it. OWASP names the httpOnly flag as the mitigation for session identifiers being readable.
- If you use cookies, plan for CSRF. Angular's HttpClient, for example, supports the client half of a token pattern, and the server must do the other half.
- Keep tokens short lived, so a theft has a short useful life.
- Reduce XSS itself: avoid raw HTML sinks, sanitize what you must render, and add a content security policy.
- Do not host several apps on one origin. They would share the same localStorage. OWASP suggests different subdomains.
Code review cues
Search for setItem and getItem calls, and look at the key names. Anything called token, jwt, session, auth or user deserves a second look. Check what happens on logout: is the value removed, and is it also revoked on the server?
Try it yourself
Click through it at your own pace, or open it full screen. Look at how authentication findings are reported for an API, the other half of a token design.
Safeguard's free scan at gold.safeguard.sh/scan checks the dependencies a front-end app ships, including any script that can read storage.
Quick check
Is sessionStorage safe for tokens?
It is narrower, since it clears when the tab closes, but scripts on the page can still read it, so XSS still exposes it.
Is a cookie always better?
An HttpOnly cookie hides the value from scripts, but cookies need CSRF protection and careful flags. Choose the design on purpose.
Sources
Last reviewed: 19 October 2026.