TL;DR: JWTs are widely used for application authentication, but insecure browser storage can expose tokens to XSS, CSRF, and extension-based theft, according to Descope’s developer guide. The core issue is not token format but where the token lives, because storage choice directly changes the compromise path and revocation options.
At a glance
What this is: This developer guide explains how common JWT storage methods work and shows that browser storage decisions materially affect token theft risk, revocation, and session security.
Why it matters: IAM and application security teams need to treat JWT storage as an identity control, because weak browser handling turns authenticated sessions into reusable credentials for both human and machine access paths.
By the numbers:
- Only 20% have formal processes for offboarding and revoking API keys, and even fewer have procedures for rotating them.
- 71% of NHIs are not rotated within recommended time frames, increasing the risk of compromise over time.
- 96% of organisations store secrets outside of secrets managers in vulnerable locations including code, config files, and CI/CD tools.
👉 Read Descope's guide to secure JWT storage methods for web apps
Context
JWT storage is an identity control problem, not just a front-end implementation detail. If a token is stored where scripts, extensions, or cross-site requests can reach it, the session becomes reusable credential material instead of a bounded authentication artefact.
For IAM and application teams, the practical question is how storage choice affects theft resistance, expiry enforcement, and revocation. That matters across human sessions, API-driven service access, and any workflow that treats a JWT as a durable bearer secret.
The guide is strongest when it compares browser storage options against concrete attack paths such as XSS and CSRF. That starting point is typical for teams modernising web authentication, and it is relevant whenever token handling crosses trust boundaries.
Key questions
Q: How should security teams store JWTs in browser applications?
A: Prefer storage patterns that reduce script readability and replay risk. HttpOnly cookies with Secure and SameSite flags are usually safer than local storage or session storage when the application can support server-side session handling or a backend-for-frontend design. The best choice depends on XSS exposure, CSRF handling, and whether the token must be readable by client-side code.
Q: Why do JWT storage decisions matter for identity security?
A: Because a JWT is a bearer credential, whoever holds it can often use it. If the browser stores that token in a place that JavaScript, injected code, or browser tooling can read, the session becomes reusable outside the intended user context. That changes authentication from a controlled session into an extractable secret.
Q: What breaks when JWTs are stored in local storage or session storage?
A: The main failure is script readability. Both storage methods are directly accessible to JavaScript, so an XSS event can expose active tokens quickly. Local storage also persists longer than session storage, which increases the time window for abuse if the token is stolen.
Q: What should teams do when JWTs must work across multiple domains or mobile apps?
A: Use a backend-for-frontend pattern for web apps that span services, or rely on platform secure storage and short-lived tokens for mobile. That keeps token handling closer to the server or device security boundary and avoids forcing browser storage patterns into environments they do not fit well.
Technical breakdown
JWT storage as a bearer-token exposure problem
A JWT is a bearer token, which means possession usually equals access. Once issued, it must be stored somewhere client-side or managed through a server-mediated pattern, and that storage location becomes part of the security model. Local storage, session storage, cookies, and memory each change the attacker’s path to token theft. The core technical issue is not whether the token is valid, but whether the client-side environment exposes it to JavaScript, browser state, or request replay.
Practical implication: treat token storage as part of the authentication design, not a post-login implementation detail.
Why local storage and session storage increase XSS impact
Local storage persists across tabs and browser restarts, while session storage persists for a tab session, but both are directly readable by JavaScript. That makes them efficient for application code and equally efficient for injected scripts. If an attacker lands XSS, either storage method can expose a live JWT quickly. Session storage reduces persistence but does not remove script-readability, so it changes dwell time more than compromise likelihood.
Practical implication: if XSS remains plausible, do not treat browser storage convenience as a compensating control.
How HttpOnly cookies and in-memory storage change the control boundary
HttpOnly cookies prevent JavaScript from reading the token, which reduces direct token exfiltration through XSS, but they introduce CSRF exposure unless SameSite and anti-CSRF controls are in place. In-memory storage keeps the token out of persistent browser storage and can reduce easy retrieval, but it is still vulnerable if the application process is compromised or instrumented. These methods shift the risk boundary rather than eliminating it, so the surrounding controls matter as much as the storage choice.
Practical implication: pair cookie-based sessions with CSRF protections, or use memory-only patterns only when the broader client threat model supports them.
Threat narrative
Attacker objective: The attacker wants a valid session token that can be replayed to impersonate the user and pivot into protected application or API access.
- Entry occurs when an attacker injects script through XSS or abuses another client-side execution path to reach the browser context holding the JWT.
- Escalation follows when the attacker reads the token from accessible storage or intercepts it before it expires, turning a user session into reusable credentials.
- Impact occurs when the stolen JWT is replayed against protected APIs, allowing impersonation, privilege abuse, and access to sensitive data or administrative functions.
Breaches seen in the wild
- Salesloft OAuth token breach — hackers stole OAuth tokens to access Salesforce data via Salesloft.
- GitHub Dependabot Breach — GitHub Dependabot tokens stolen and abused to push malicious commits to repositories.
Read our 52 NHI Breaches Analysis report for a comprehensive view of breaches impacting Non-Human Identities including AI Agents.
NHI Mgmt Group analysis
JWT storage is really bearer-credential governance. The article treats storage as an implementation choice, but the identity issue is whether the token can be extracted, replayed, and reused outside the intended session boundary. That is the same governance question we ask for NHIs: where does the secret live, who can read it, and how quickly can it be revoked. Practitioners should classify browser-held JWTs as reusable credentials and govern them accordingly.
Browser convenience and identity safety pull in opposite directions. Local storage and session storage are easy to use because they are directly available to application code, but that same accessibility makes them poor containment points for sensitive tokens. Cookies reduce script visibility, while in-memory storage reduces persistence, yet neither removes the need for upstream controls such as XSS prevention, CSRF defenses, and short-lived token design. The right decision is about control exposure, not developer convenience.
JWT handling belongs in the same risk conversation as secrets sprawl. A token stored in a browser is still a secret with an attack surface, and it should be subject to the same discipline as any other credential. The relevant named concept here is token storage trust boundary: the point at which application convenience stops and credential governance begins. Once that boundary is unclear, teams lose visibility into where access can be stolen or replayed.
Stateless token design does not remove lifecycle responsibility. The guide shows that expiration, rotation, logout, and revocation remain necessary even when the token is self-contained. That means identity teams cannot treat JWTs as fire-and-forget artefacts once issued. The practical conclusion is that bearer-token lifecycle has to be designed into the session model from the start, not patched on later.
Cross-domain and mobile scenarios expose the limits of simple browser patterns. The article’s discussion of backend-for-frontend patterns, mobile secure storage, and session identifiers shows that token handling becomes a distribution problem as soon as the application spans devices or domains. That is where governance, not just coding practice, determines whether access can be contained. Teams should align token storage with the operating context, not force one pattern everywhere.
From our research:
- Only 20% have formal processes for offboarding and revoking API keys, and even fewer have procedures for rotating them, according to the Ultimate Guide to NHIs.
- 91.6% of secrets remain valid five days after the targeted organisation is notified, showing how slowly credential exposure is removed in practice.
- That lifecycle lag is why our Ultimate Guide to NHIs is a useful next step for teams formalising revocation, rotation, and offboarding.
What this signals
JWT handling is converging with broader identity governance because browser-held tokens behave like reusable credentials once they leave the server. Token storage trust boundary: teams need a clear rule for when a session token becomes a secret, how it is protected in the client, and what conditions force immediate revocation. The hard part is not choosing one storage method, but designing the surrounding controls so the token cannot outlive the risk model it was issued under.
The stronger programme signal is that authentication design now has to account for both human and non-human access paths. When applications use the same token mechanics for web sessions, API calls, and backend services, token handling becomes a lifecycle problem across the identity estate. That is where JWT storage decisions start to overlap with secrets management, workload identity, and access review discipline.
For practitioners
- Move sensitive JWTs out of directly script-readable storage Prefer HttpOnly cookies or a backend-for-frontend pattern when a browser app must hold an access token, and reserve local storage only for low-risk scenarios with strong XSS hardening.
- Pair cookie sessions with anti-CSRF controls If you use cookies for JWT transport, enforce HttpOnly, Secure, and SameSite settings and add an explicit anti-CSRF mechanism for state-changing requests.
- Shorten token lifetime and design revocation paths Use short-lived access tokens, defined refresh logic, and server-side revocation or blacklist handling so a stolen JWT cannot remain useful for long.
- Harden the client against script-based token theft Apply a strict Content Security Policy, eliminate avoidable XSS sinks, and test browser extension and debugger exposure where the application depends on session or in-memory token handling.
Key takeaways
- JWT storage is an identity control decision because bearer tokens become reusable credentials if they are exposed to the browser attack surface.
- Local storage and session storage are convenient but directly script-readable, which makes XSS a token theft path rather than just a page-level issue.
- Cookie-based and in-memory approaches reduce some exposure, but they only work when paired with CSRF protection, short-lived tokens, and a revocation plan.
Standards & Framework Alignment
This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.
OWASP Non-Human Identity Top 10 address the attack and risk surface, while NIST CSF 2.0, NIST Zero Trust (SP 800-207) and NIST SP 800-53 Rev 5 set the governance and control requirements practitioners need to meet.
| Framework | Control / Reference | Relevance |
|---|---|---|
| OWASP Non-Human Identity Top 10 | NHI-03 | JWTs function as reusable credentials when stored insecurely in the browser. |
| NIST CSF 2.0 | PR.AC-4 | The article is fundamentally about controlling access to protected resources through token handling. |
| NIST Zero Trust (SP 800-207) | JWT transport and validation sit inside a broader zero trust session model. | |
| NIST SP 800-53 Rev 5 | IA-5 | JWTs are authenticators that require lifecycle and protection discipline. |
Verify the requester and the token context continuously rather than trusting browser persistence alone.
Key terms
- Json Web Token: A JSON Web Token is a compact, signed token that carries claims between systems so they can verify identity or authorization without consulting a central session store. In practice, its safety depends on strict validation of the signature, issuer, audience, expiry, and algorithm before any trust decision is made.
- Bearer Token: A bearer token is a credential that grants access to whoever possesses it, without requiring strong proof that the holder is the intended client. In NHI environments, that makes theft and replay the main risk, especially when tokens are long-lived, broadly scoped, or stored in local files.
- HttpOnly Cookie: An HttpOnly cookie is a session cookie that JavaScript cannot read, which reduces the risk of theft through client-side script compromise. In BFF architectures, it is a common way to keep authentication material out of browser-accessible storage while still allowing the server to authorize requests.
- Backend For Frontend: A backend for frontend is a server-side layer built specifically for one client application, such as a web app or mobile app. It aggregates data, enforces session checks, and keeps privileged API credentials away from distributed client code, which makes it a control boundary as well as an architecture pattern.
What's in the full article
Descope's full blog post covers the implementation detail this post intentionally leaves at the architectural level:
- Step-by-step code examples for storing, reading, and clearing JWTs in local storage, session storage, cookies, and memory.
- Browser-specific implementation notes for HttpOnly, Secure, SameSite, and refresh handling across common web application patterns.
- Mobile storage guidance for Android Keystore, SharedPreferences, and iOS Keychain when JWTs must live on device.
- Troubleshooting tips for cross-domain cookie behaviour and backend-for-frontend session design.
Deepen your knowledge
NHI governance, agentic AI identity, and machine identity lifecycle are core topics in our NHI Foundation Level course, the industry's only accredited NHI security programme. If you are responsible for identity security strategy or NHI governance in your organisation, it is worth exploring.
Published by the NHIMG editorial team on August 19, 2026.
NHI Mgmt Group — the independent authority on Non-Human Identity, IAM, and Agentic AI security. nhimg.org