JWTs or session tokens stored in localStorage
Last updated October 18, 2026
Steps
- In your own app, open DevTools → Application → Local Storage / Session Storage and look for access tokens, refresh tokens, JWTs or session IDs.
- Search the client bundle for localStorage.setItem, sessionStorage.setItem, or libraries that persist auth to web storage.
- Move authentication to HttpOnly; Secure; SameSite=Strict (or Lax) cookies set by your server, or use a Backend-for-Frontend that holds tokens server-side.
- If you must use bearer tokens in a SPA, keep short-lived access tokens in memory only and put refresh tokens in HttpOnly cookies—not in localStorage.
- Clear any client storage on logout, and enforce idle/absolute timeouts on the server so a stolen token expires quickly.
- Fix XSS first: sanitize HTML, avoid dangerous innerHTML, lock down third-party scripts, and set a Content-Security-Policy—token storage alone does not stop XSS.
Why it matters
OWASP's Session Management Cheat Sheet warns not to store authentication tokens, session IDs, JWTs, refresh tokens or credentials in localStorage or sessionStorage, because any JavaScript on the origin can read them. The OWASP Web Security Testing Guide (WSTG-CLNT-12) lists JWT storage in browser storage as a common client-side risk that raises the impact of XSS.
Sources
OWASP Session Management Cheat Sheet (HTML5 Web Storage) — https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html
OWASP WSTG: Testing Browser Storage (WSTG-CLNT-12) — https://wstg.owasp.org/latest/4-Web_Application_Security_Testing/11-Client-side/12-Browser_Storage/
Related patterns
Want an expert to check your app?
VibeRescue checks are coming soon. Join the waitlist — we only check apps you own, after verification. No scanning product is live yet.
Join the waitlistVibe Security Weekly
One email a week with new failure patterns and how to fix them.
Free. Unsubscribe anytime. We'll never sell your email.