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.
Why This Matters for Security Teams
JWT storage is not just a frontend implementation detail. It determines whether a stolen token can be replayed from a browser compromise, whether cross-site scripting can turn into account takeover, and whether a session can be revoked cleanly after risk is detected. In browser applications, the most common mistake is optimising for developer convenience rather than limiting script access and replay scope. That is especially dangerous when the token represents API access, administrative functions, or downstream service calls.
Security teams should treat JWT placement as part of the broader session architecture, not as a standalone choice. Guidance from the NIST Cybersecurity Framework 2.0 aligns with this view: identity, access, and protective controls should work together rather than be bolted onto a client app after the fact. NHIMG research on the Ultimate Guide to NHIs shows how frequently secrets exposure turns into real compromise, and the same pattern applies when browser-held tokens are easy to read or reuse. In practice, many security teams encounter token theft only after a frontend XSS issue or debug artifact has already exposed a live session.
How It Works in Practice
The safest common pattern is to keep the JWT out of JavaScript-readable storage whenever the application architecture allows it. A server-side session or backend-for-frontend design can place the token in an HttpOnly cookie with Secure and SameSite controls, so the browser sends it automatically but client scripts cannot read it. That reduces the blast radius of XSS because an attacker who injects JavaScript has a harder time exfiltrating the token directly.
When teams must support client-side token handling, the decision becomes a risk tradeoff. Local storage and session storage are easy to implement, but both are readable by JavaScript, which makes them poor choices when XSS exposure is material. Current guidance suggests limiting those patterns to narrow cases where the token is short-lived, the app is heavily hardened, and the team has a strong reason the frontend must read the token. Even then, storing only an access token in memory and keeping refresh capability server-side is usually safer than persisting long-lived credentials in the browser.
- Use HttpOnly, Secure, SameSite cookies when server-side session handling is available.
- Keep JWT lifetimes short and design for rotation or re-authentication.
- Avoid storing refresh tokens in JavaScript-accessible browser storage.
- Pair cookie-based sessions with CSRF protections, because HttpOnly does not stop cross-site request abuse.
- Validate whether the token truly needs to be readable by the frontend; many apps only need it sent automatically.
NHIMG analysis of the State of Non-Human Identity Security highlights how often credential control failures lead to compromise, which is a useful reminder that token location matters as much as token strength. These controls tend to break down when single-page apps must call multiple domains directly, because the token has to be exposed to browser code and revocation becomes harder to enforce quickly.
Common Variations and Edge Cases
Tighter token storage often increases implementation overhead, requiring organisations to balance reduced replay risk against CSRF handling, session complexity, and operational convenience. There is no universal standard for this yet, especially across hybrid applications that mix browser rendering, third-party APIs, and native-like frontend flows. The right answer depends on whether the app can tolerate server affinity, whether the token must be inspected in the browser, and how much risk the organisation accepts from XSS.
One common edge case is third-party identity providers that issue JWTs for direct use in the browser. In those environments, best practice is evolving toward short-lived access tokens, refresh flows that are not exposed to arbitrary scripts, and strong content security controls. Another edge case is microfrontend or embedded-widget architectures, where multiple scripts share the same origin and the practical XSS surface is larger than teams expect. If the frontend must hold the token briefly, memory-only storage is usually preferable to persistent browser storage, but it still does not solve token theft if the page is compromised.
The safest pattern is not “where can a JWT be stored,” but “how little access does the browser really need to hold.” That framing is what usually keeps teams from turning an authentication token into a long-lived browser secret.
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, OWASP Agentic AI Top 10 and CSA MAESTRO address the attack and risk surface, while NIST CSF 2.0 and NIST AI RMF set the governance and control requirements practitioners need to meet.
| Framework | Control / Reference | Relevance |
|---|---|---|
| NIST CSF 2.0 | PR.AC-1 | Token storage affects authentication proof and session access control. |
| OWASP Non-Human Identity Top 10 | NHI-01 | JWTs are non-human credentials and must be protected from exposure and reuse. |
| OWASP Agentic AI Top 10 | Script-readable tokens are risky in autonomous browser-driven workflows too. | |
| CSA MAESTRO | Browser token handling should support workload boundaries and runtime trust decisions. | |
| NIST AI RMF | Token handling is part of secure AI-enabled application governance and risk control. |
Store browser JWTs in ways that preserve least-privilege access and minimize replay exposure.