CSS-002 recommended Storage

Browser storage used appropriately

localStorage limited to preferences/UI state; no tokens, secrets, or PII in browser storage

Question to ask

"Any tokens sitting in localStorage right now?"

Verification guide

Severity: Recommended

localStorage persists indefinitely and is accessible to any JS on the domain (XSS risk). Should only store non-sensitive data like UI preferences. sessionStorage clears on tab close - better for temporary state. Never store tokens, secrets, or PII in either.

Check automatically:

  1. Find all localStorage usage:
# All localStorage calls
grep -rE "localStorage\.(get|set|remove)Item|localStorage\[" --include="*.ts" --include="*.js" --include="*.tsx" --include="*.jsx" src/ 2>/dev/null
  1. Find all sessionStorage usage:
grep -rE "sessionStorage\.(get|set|remove)Item|sessionStorage\[" --include="*.ts" --include="*.js" --include="*.tsx" --include="*.jsx" src/ 2>/dev/null
  1. Check what's being stored (look for sensitive patterns):
# Red flags: tokens, auth, jwt, session, password, secret, key
grep -rE "localStorage\.setItem\s*\(\s*['\"]" --include="*.ts" --include="*.js" --include="*.tsx" -A1 src/ 2>/dev/null | grep -iE "token|auth|jwt|session|password|secret|key|user"
  1. Check for storage abstraction layers:
# Custom hooks or utilities that wrap storage
grep -rE "useLocalStorage|useStorage|storageService|localStorageUtil" --include="*.ts" --include="*.js" src/ 2>/dev/null
  1. Review storage keys (naming reveals intent):
# Extract all storage key names
grep -rhoE "localStorage\.(get|set)Item\s*\(\s*['\"][^'\"]+['\"]" --include="*.ts" --include="*.js" --include="*.tsx" src/ 2>/dev/null | sort -u

Acceptable localStorage uses:

  • Theme preference (dark/light mode)
  • Language/locale preference
  • UI state (sidebar collapsed, dismissed banners)
  • Feature flags (non-security)
  • Anonymous analytics IDs

Not acceptable in localStorage:

  • JWT tokens, access tokens, refresh tokens
  • Session identifiers
  • User PII (email, name, etc.)
  • API keys or secrets

Cross-reference with:

  • CSS-001 (sensitive data should be in HttpOnly cookies, not storage)
  • CSS-003 (JWT handling practices)

Pass criteria:

  • localStorage only used for preferences/UI state
  • No tokens or auth data in localStorage
  • sessionStorage used for temporary state that should clear on tab close

Fail criteria:

  • JWT/auth tokens in localStorage
  • PII stored in localStorage
  • Sensitive data in either storage type

Evidence to capture:

  • All localStorage keys found and their purpose
  • Any sessionStorage usage and purpose
  • Red flags (tokens, auth data in storage)
  • Storage abstraction utilities (if any)

Section

23. Client-Side Security & Storage

Infrastructure Features