ブラウザのどこに置くか — 読まれる・消える
ブラウザにデータを置くとき、先に決めるのは保存先ではなく、2 つの問いです。そのデータが XSS(クロスサイトスクリプティング)で読まれたら困るか。消えたら困るか。保存先ごとの測定結果は、ブラウザの保存先 7 種に書きました。ここでは、その結果から、データの種類ごとの置き場を決めます。
結論は、ログインの印は HttpOnly を付けた Cookie、画面の設定は localStorage、大きなデータは IndexedDB か OPFS(正本はサーバー)、鍵はブラウザに置かない、拡張機能の機密データは chrome.storage.session です。
先に答える問いは何か?
| 問い | 測定で分かったこと | 「はい」のとき |
|---|---|---|
| XSS で読まれたら困るか | 6 種は全部読まれた。取り出せない鍵で暗号化しても復号された | 保存先を変えても解決しない。XSS を防ぐ対策が先。ブラウザに置かない選択もある |
| 消えたら困るか | 閲覧データの削除で、ページ側の 6 種は消えた。chrome.storage は消えなかった | 正本をサーバーに持ち、ブラウザには写しだけを置く |
| ディスクを読まれたら困るか | Cookie の値以外は、ディスクの上で平文 | ブラウザの外(OS のログインとディスクの暗号化)で守る |
3 つの問いの答えが決まったら、データの種類ごとに置き場を選びます。
データの種類ごとに、どこに置けばよいのか?
- ログインの印: HttpOnly を付けた Cookie。値は XSS でも読まれませんでした。
- 画面の設定: localStorage。XSS で読まれるので、読まれても困らない内容だけにします。
- 大きなデータ: IndexedDB か OPFS。XSS で読まれ、閲覧データの削除で消えるので、正本はサーバーに置きます。
- 鍵・暗号化したデータ: ブラウザには置きません。取り出せない設定の鍵でも、XSS では復号され、ディスクに生のバイトが見つかりました。
- 拡張機能の設定: chrome.storage の sync か local。ディスクの上では平文です。
- 拡張機能の機密データ: chrome.storage.session。既定ではコンテンツ スクリプトから読めず、ディスクにも書かれません。3 つの領域の違いは拡張機能の保存先にあります。
Chrome for Developers(chrome.storage)原文
Items in the session storage area are stored in-memory and will not be persisted to disk.
出典を開く確認 2026-11-02
測定の根拠は、ブラウザの保存先 7 種にあります。ログインの印だけは、Cookie と localStorage の差が大きいので、次の節で詳しく比べます。
ログインの印は、Cookie と localStorage のどちらに置くのか?
| 比べること | localStorage | Cookie(HttpOnly) |
|---|---|---|
| XSS で値を読まれるか | 読まれた | 読まれなかった |
| XSS で使われるか | 値を持ち出されて使われる | その Cookie を付けた要求を送られた MDN(Set-Cookie header)原文a cookie that has been created with HttpOnly will still be sent with JavaScript-initiated requests出典を開く確認 2026-11-02 |
| ディスクの上 | 平文で見つかった | 暗号化されていた |
| サーバーへ自動で送られるか | 送られない | 送られる |
| 入る量 | 約 520 万文字 | 1 つで約 4 KB |
HttpOnly は、値を持ち出されることを防ぎますが、XSS があるあいだ、その利用者として要求を送られることは防げません。ログインの印を Cookie に置いても、XSS を防ぐ対策は別に要ります。Secure や SameSite の属性と、Content Security Policy の効果は測っていません。では、「IndexedDB に移す」「暗号化する」は、守りになるのでしょうか。
「IndexedDB に移す」「暗号化する」は、守りになるのか?
| よくある考え | 測定で分かったこと |
|---|---|
| localStorage をやめて IndexedDB に置けばよい | IndexedDB も、XSS では 3 ブラウザとも読まれた |
| 暗号化して置けばよい | 取り出せない設定の鍵で暗号化しても、同じページのスクリプトは復号できた。鍵の生のバイトは、ディスクの IndexedDB のファイルに見つかった |
| chrome.storage なら、ページから見えないので安全 | ページからは呼べなかった。ただし同じ拡張機能のコンテンツ スクリプトは local と sync を読め、ディスクの上は平文だった |
| HttpOnly を付けたので安全 | 値は読まれなかったが、その Cookie を付けた要求は送られた |
どの置き場でも、同じページの中で動くスクリプトには、ページと同じ権限があります。この表の考えが守りにならなかったのは、保存先ではなく、スクリプトが動いたことが原因だからです。
何が決まらないのか?
| 測っていないこと | 決まらないこと |
|---|---|
| 対策側 | Content Security Policy・Cookie の Secure と SameSite・入力の無害化が、XSS をどこまで防ぐか |
| ほかのブラウザと端末 | Firefox・スマートフォンのブラウザ・Windows の Chrome での結果 |
| 消え方 | Safari の 7 日の規則 WebKit(ブログ)原文deleting all of a website’s script-writable storage after seven days of Safari use without user interaction on the site出典を開く確認 2026-11-02 |