In May 2026, an article titled Why people say "stop storing JWTs in localStorage": A chronological overview leading to the return of cookies (Zenn 2026-05-27) trended widely. Sparked by a post on X from prominent web security expert Hiroshi Tokumaru, it highlighted that SPA architectures storing JWTs in localStorage are vulnerable to XSS. The article carefully traced the history of how Authorization header approaches briefly became standard and why there has recently been a "resurgence" toward session architectures backed by HttpOnly cookies.
At our firm, requests for client services to "audit the authentication implementation of our existing web app / SPA" have been rising. Most clients say, "It works, but we lack confidence in whether our token storage location and refresh flow design are truly secure." This article formalizes these concerns into our "web authentication implementation security audit" service, breaking down the process from diagnosis to remediation and ongoing operations. For underlying threat models, see Introduction to Web Security; for replacing the auth platform itself, consult Better Auth / Supabase / Clerk Authentication Migration for Clients.
Why "token storage location is a turning point"
The crux of the debate is "where to store access tokens." While localStorage is freely accessible via JavaScript, HttpOnly cookies cannot be read by scripts. This fundamental difference determines overall XSS resilience.
| Dimension | localStorage storage + Authorization header | HttpOnly cookie + proper flags |
|---|---|---|
| Token theft via XSS | High risk of exfiltration because it is readable via JS | Unreadable via JS due to HttpOnly, making theft difficult |
| CSRF | Inherently unlikely due to explicit header injection | Requires defenses using SameSite=Lax/Strict + CSRF tokens |
| Third-party cookie restrictions | Largely unaffected | Requires caution for cross-site use (assumes first-party) |
| Cross-origin API calls | Relatively straightforward via CORS configuration | Requires careful domain design and SameSite adjustment |
| Implementation complexity | Deceptively simple, but hinges on robust XSS defenses | Robust, but requires server-side sessions / BFF |
The key takeaway is that "neither approach is a silver bullet." While the localStorage pattern can work if XSS is strictly contained through CSP and input sanitization, it possesses a single point of failure: a single XSS flaw exposes all tokens to theft. Conversely, cookie-based architectures require proper CSRF defenses and correct SameSite configuration. Our audits evaluate whether an application meets the prerequisites required by its specific threat model.
Three structural changes beneficial to custom development projects
Structural shift 1: Moving from "as long as it works" to "threat-model-driven auth design"
Whereas previously "being able to log in" was sufficient, applications are now scrutinized on whether XSS, CSRF, open redirects, and token fixation are explicitly modeled and paired with concrete countermeasures. In custom development, documenting threat models during requirement definition and preserving architectural rationales delivers clear value. The breakdown in Introduction to Web Security serves as an effective starting point for identifying threats.
Structural shift 2: From frontend-only to the resurgence of BFF and cookie sessions
There is an accelerating swing away from architectures where the SPA frontend holds tokens on its own toward setups where a Backend for Frontend (BFF) manages tokens and issues only an HttpOnly cookie session ID to the browser. In custom development, the architectural expertise to seamlessly integrate a BFF without breaking the existing SPA creates a major competitive advantage.
Structural shift 3: From one-off audits to ongoing security operations
Vulnerabilities in third-party libraries and scripts emerge continuously. Demand is rising for ongoing re-audit workflows rather than single assessments. Adopting the concepts from our SCS (Security Evaluation) Guide, we establish evaluation frameworks for regular, scheduled monitoring.
The 5 phases of client-provided "web authentication implementation security audits"
Phase 1: Current-state assessment
- Inventory token storage locations (
localStorage,sessionStorage, cookies, memory) - Diagram authentication flows (login, refresh, logout, revocation)
- Review dependencies, versions, and known vulnerabilities
Phase 2: Threat evaluation
- Inspect for XSS, CSRF, open redirects, and token fixation
- Verify current configuration of CSP,
SameSite,HttpOnly, andSecureflags - Evaluate refresh token expiration, rotation, and revocation mechanisms
Phase 3: Remediation design
- Establish token storage strategy (determine need for cookie sessions / BFF)
- Design CSP policies (evaluating
nonce/strict-dynamicadoption) - Design refresh token rotation and revocation blocklists
Phase 4: Remediation implementation and PR review
- Implement remediation code or review existing pull requests
- Verify configuration of
SameSite,HttpOnly, andSecureflags - Add automated tests (authentication flow, revocation, CSRF)
Phase 5: Re-audit and operations (ongoing)
- Conduct post-remediation audit and differential verification
- Perform routine monitoring of dependency vulnerabilities and CSP violation reports
- Establish incident response playbooks for token revocation and rotation
Standard technology stack set for custom development
| Layer | Recommendation | Alternative |
|---|---|---|
| Authentication method | Server sessions + BFF | OIDC / OAuth 2.1 (external IdP) |
| Token storage | HttpOnly + Secure + SameSite Cookie | In-memory storage (short-lived access tokens) |
| CSP / headers | CSP (nonce-based) + HSTS + X-Content-Type-Options | Phased rollout starting with report-only mode |
| CSRF defense | SameSite + Double Submit / Synchronizer Token | Combined Origin / Referer validation |
| Audit and inspection tools | Dependency vulnerability scanning + DAST + CSP report collection | Paired with manual code review |
Tools are merely aids; "design decisions grounded in the threat model" remain paramount.
Which projects need this and which do not
| Scenarios requiring an audit | Scenarios where an audit is excessive |
|---|---|
SPAs storing tokens in localStorage | Static websites without authentication features |
| Applications handling personal data or payment details | Internal, closed staging or testing tools |
| Ambiguous or undocumented refresh token architectures | Fully delegated to managed IdPs with zero custom code |
| Applications loading numerous third-party scripts | Public, read-only content portals |
Six clauses to include in client contracts
| Clause | Details | What the client should verify |
|---|---|---|
| Audit scope | Explicit listing of target apps, domains, and out-of-scope assets | Clarify whether subdomains and external APIs are included |
| Inspection methodology | Static, dynamic, and manual techniques with non-destructive guarantees | Feasibility and terms for production testing |
| Remediation responsibilities | Reporting only versus implementation inclusion | Demarcation from client in-house development tasks |
| Handling of PoC artifacts | Storage and secure disposal of obtained credentials and PoCs | Confidentiality terms and retention timelines |
| Critical vulnerability notification | Immediate reporting workflows based on severity | Communication channels and SLA |
| Re-audit terms | Scope and frequency of post-remediation verification | Presence or absence of additional fees |
Client-side ROI estimate
| Benefit | Estimation rationale |
|---|---|
| Data breach prevention | Avoid incident response, notification, and compensation costs |
| Reduced remediation rework | Pre-release fixes cut production patching overhead |
| Vulnerability management labor | Monthly operations smooth out ad-hoc patching spikes |
| Maintaining partner trust | Supports B2B ongoing contracts and creditworthiness |
Even if an initial investment of around 1.4 million yen is made for a spot audit and remediation implementation, this is typically orders of magnitude smaller than the cost of responding to a single major security incident (investigations, disclosures, compensation, and reputational loss). For applications handling personal data or payment processing, the expected value of avoided losses easily justifies the cost.
Five common pitfalls
Pitfall 1: Merely moving from localStorage to cookies
Switching storage locations without implementing SameSite or CSRF defenses simply substitutes one risk for another. Migrations must be executed with a complete set of security controls.
Pitfall 2: Leaving CSP unconfigured
Without CSP as the last line of defense against XSS, script injection causes extensive damage whether tokens reside in localStorage or cookies. A pragmatic approach is a phased rollout starting from report-only.
Pitfall 3: Effectively indefinite refresh token lifespans
Long-lived refresh tokens cause catastrophic damage if stolen. Incorporate rotation and revocation lists into your architecture.
Pitfall 4: Clinging to pure SPA architectures without introducing a BFF
As long as tokens are held in the frontend, they remain within reach of XSS. When handling sensitive data, consider hiding tokens behind a BFF.
Pitfall 5: Ignoring third-party scripts
External scripts like advertising, analytics, and chat widgets can serve as entry points for XSS. You must inventory external scripts and enforce allowlists via CSP.
90-day action plan
| Week | Initiative |
|---|---|
| Weeks 1–2 | Inventory token storage locations and diagram authentication flows |
| Weeks 3–4 | Threat evaluation for XSS, CSRF, and open redirects |
| Weeks 5–6 | Current-state review of CSP, SameSite, and HttpOnly, and definition of remediation policies |
| Weeks 7–9 | Remediation implementation, PR reviews, and adding tests |
| Weeks 10–11 | Phased rollout of BFF and cookie session migration |
| Weeks 12–13 | Re-audit, operationalizing recurring health checks, and handover |
Conclusion
The debate over "don't store JWTs in localStorage" is not simply about "solving everything by changing the storage location"; rather, it calls for revisiting your entire authentication architecture against your threat model. When viewed holistically—spanning HttpOnly, Secure, SameSite, CSP, refresh token architecture, and BFFs—the key decision criterion, whether you choose localStorage or cookies, is whether the prerequisites are met. Our Web Authentication Implementation Security Audit provides hands-on support from diagnostic assessment and remediation to continuous operation. If you have any concerns about your existing application's authentication, please feel free to reach out via our contact form.
Sources
- Why people say "don't store JWTs in localStorage": A chronological recap leading up to the return to cookies (Zenn, 2026-05-27)
- OWASP general best practices for authentication and session management (Cheat Sheets, etc.)
- Introduction to Web Security
- SCS (Security Evaluation) Guide
- Client authentication migration to Better Auth, Supabase, and Clerk








