← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

Browser Storage APIs

frontend HTML5 Beginner
debt(d5/e3/b3/t7)
d5 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'specialist tool catches it' (d5). The detection_hints list semgrep, eslint, and lighthouse — these are specialist/SAST tools that can detect patterns like JWT tokens in localStorage or missing cookie flags. They are not default linters (which would be d3), but dedicated tools that must be configured to catch this pattern.

e3 Effort Remediation debt — work required to fix once spotted

Closest to 'simple parameterised fix' (e3). The quick_fix describes a clear replacement pattern: swap localStorage for sessionStorage or HttpOnly cookies depending on use case. This is a targeted find-and-replace refactor within the storage layer — not a one-liner (e1) but not multi-file architectural rework either.

b3 Burden Structural debt — long-term weight of choosing wrong

Closest to 'localised tax' (b3). The applies_to scope is web contexts only, and the burden falls on the storage/auth layer of a given application. It doesn't reshape the entire codebase, but the wrong storage choice for auth tokens can require revisiting auth flows in one component area.

t7 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'serious trap' (t7). The misconception field directly states the canonical wrong belief: 'localStorage is a safe place to store authentication tokens.' This contradicts how many developers reason about storage (treating it like a secure server-side store), and the 'obvious' approach of storing JWTs in localStorage is exactly the insecure one. This is a well-documented gotcha that contradicts reasonable analogies from other storage paradigms.

About DEBT scoring →

Also Known As

localStorage sessionStorage IndexedDB browser storage API

TL;DR

localStorage, sessionStorage, IndexedDB, and cookies — different scopes, capacities, and access patterns for client-side data persistence.

Explanation

localStorage: synchronous key-value store, persists until cleared, ~5MB, same-origin only — suitable for user preferences and non-sensitive settings. sessionStorage: same API, cleared when tab closes — suitable for single-session state. Both are accessible to JavaScript on the same origin, making them vulnerable to XSS attacks — never store tokens or sensitive data. IndexedDB: asynchronous, structured, transactional, gigabytes of capacity — for offline apps and caching large datasets; use a wrapper library (Dexie.js) to avoid verbose raw API. Cookies: sent to server on every request, support HttpOnly (JS-inaccessible), Secure, SameSite, and domain/path scoping — the correct storage for session tokens. Cache API (Service Workers): for offline asset caching. PHP sets HttpOnly cookies server-side, making them invisible to JavaScript and XSS-resistant.

Common Misconception

localStorage is a safe place to store authentication tokens. localStorage is accessible to any JavaScript on the page — an XSS vulnerability exposes all stored tokens. HttpOnly cookies are inaccessible to JavaScript and are the secure alternative for authentication tokens.

Why It Matters

localStorage, sessionStorage, and cookies serve different persistence and security needs — storing sensitive data in localStorage exposes it to XSS because JavaScript can read it without restriction.

Common Mistakes

  • Storing JWT tokens or session tokens in localStorage — XSS can steal them via document.cookie-equivalent access.
  • Not setting HttpOnly and Secure flags on sensitive cookies — accessible to JavaScript and sent over HTTP.
  • Using localStorage for data that should expire with the browser session — use sessionStorage instead.
  • Not considering that localStorage is synchronous and blocking — large reads/writes freeze the main thread.

Code Examples

✗ Vulnerable
// Storing session token in localStorage — accessible to XSS
localStorage.setItem('auth_token', token);
✓ Fixed
// Session tokens: use HttpOnly cookie (server sets it, JS can't read it)
// Set-Cookie: session=...; HttpOnly; Secure; SameSite=Strict

// localStorage is fine for non-sensitive preferences
localStorage.setItem('theme', 'dark');
localStorage.setItem('language', 'en');

// sessionStorage for single-tab state (form wizard progress)
sessionStorage.setItem('checkout_step', '2');

Added 15 Mar 2026
Edited 22 Mar 2026
Views 23
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings F 0 pings S 0 pings S 1 ping M 1 ping T 0 pings W 0 pings T 0 pings F 1 ping S 0 pings S 1 ping M 0 pings T 0 pings W 0 pings T 0 pings F 1 ping S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 1 ping S 0 pings S 0 pings M 2 pings T 1 ping W 0 pings T 0 pings F 0 pings S
No pings yet today
No pings yesterday
Amazonbot 6 Google 4 Perplexity 3 Ahrefs 3 Unknown AI 3
crawler 17 crawler_json 1 pre-tracking 1
DEV INTEL Tools & Severity
🟠 High ⚙ Fix effort: Low
⚡ Quick Fix
Use sessionStorage for per-tab data, localStorage for preferences, cookies with HttpOnly+Secure+SameSite for auth tokens — never store JWTs or sensitive data in localStorage
📦 Applies To
javascript HTML5 web
🔗 Prerequisites
🔍 Detection Hints
JWT or auth token in localStorage; sensitive PII in sessionStorage; no SameSite attribute on auth cookie
Auto-detectable: ✓ Yes semgrep eslint lighthouse
⚠ Related Problems
🤖 AI Agent
Confidence: Medium False Positives: Medium ✗ Manual fix Fix: Medium Context: File
CWE-312 CWE-922

✓ schema.org compliant