Safeguard
Security Guides•

Should a single page app keep session tokens in localStorage?

OWASP advises against session identifiers in localStorage because any XSS can read them. See what to store there, what not to, and safer options to weigh.

Safeguard Security Team
3 min read

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

DatalocalStorage or sessionStorage?Reason
Theme, language, UI layoutFineNo authority attached
Draft text a user is typingFine, with careLow sensitivity, treat as untrusted on read
Session identifiersNoAlways readable by JavaScript
Access or refresh tokensAvoid, weigh alternativesOne XSS reads them
Personal dataAvoidSame 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

  1. 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.
  2. 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.
  3. Keep tokens short lived, so a theft has a short useful life.
  4. Reduce XSS itself: avoid raw HTML sinks, sanitize what you must render, and add a content security policy.
  5. 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.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.