「ストレージは安全な金庫」ではない、という前提から始めよう
localStorage / sessionStorage は便利ですが、
「ここに入れておけば安全」な場所ではありません。
ブラウザの中にあるとはいえ、
JavaScript から普通に読めるし、
悪意あるスクリプトが紛れ込めば、そこからも読めます。
まずはこの前提を強く持ってください。
「ストレージは“ちょっとしたメモ帳”であって、“秘密の金庫”ではない」
ここを勘違いすると、一気に危険な設計になります。
一番大事な原則:秘密情報を入れない
「盗まれたら終わるもの」は絶対に置かない
まず、これだけははっきり言い切ります。
パスワード、本物の認証トークン、クレジットカード情報など
“盗まれたら終わるもの”を localStorage / sessionStorage に入れてはいけません。
理由はシンプルです。
ストレージの中身は、
同じオリジンで動く JavaScript から自由に読めます。
もし XSS(クロスサイトスクリプティング)攻撃で
悪意あるスクリプトを埋め込まれてしまったら、
そのスクリプトから localStorage の中身は丸見えです。
// 攻撃者側のコードのイメージ
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
const value = localStorage.getItem(key);
// これを自分のサーバーに送る…
}
JavaScriptあなたがどれだけ丁寧に setItem / getItem を書いても、
「一度ブラウザに置いた秘密情報は、XSS が起きた瞬間に盗まれうる」
という現実は変わりません。
だからこそ、
「そもそも置かない」という設計が一番強いです。
「トークンを localStorage に入れるな」がよく言われる理由
SPA などでよくあるのが、
「ログイン後のアクセストークンを localStorage に保存する」パターンです。
localStorage.setItem("accessToken", token);
JavaScriptこれをやると、
XSS が起きた瞬間に accessToken が盗まれ、
攻撃者がユーザーになりすまして API を叩けるようになります。
「でも、どこかには保存しないと…」と思うかもしれませんが、
その議論はもう一段深い話になります。
初心者としてまず持っておいてほしいのは、
「localStorage は“長期保存できるから便利”だけど、
“長期保存されるからこそ、盗まれたときのダメージも大きい”」
という感覚です。
XSS とストレージの関係をちゃんとイメージする
XSS が起きると何ができるのか
XSS(クロスサイトスクリプティング)は、
「本来そのサイトが意図していない JavaScript が、ユーザーのブラウザで実行されてしまう攻撃」です。
一度 XSS が成立すると、そのスクリプトは
document.cookie を読むlocalStorage / sessionStorage を読む
フォームの入力を盗み見る
画面を書き換える
など、そのページ上であなたのコードができることは、ほぼ何でもできます。
つまり、
「XSS が起きたら localStorage の中身は全部見られる」
と考えておくのが現実的です。
「守る」より「置かない」ほうが強い
XSS 対策はもちろん重要ですが、
それでも「絶対に 0% にはできない」世界です。
だからこそ、
「XSS が起きても致命的な情報が盗まれないようにする」
という発想が必要になります。
そのための一番シンプルで強いルールが、
「localStorage / sessionStorage に、盗まれたら終わる情報を置かない」
です。
これは、
「鍵をかける技術」ではなく、
「そもそもそこに宝物を置かない」という設計の話です。
JSON で保存するときの「見え方」も意識する
JSON だからといって安全になるわけではない
よくある誤解として、
「JSON にして保存しているから、ちょっとは安全」
という感覚がありますが、
これは完全に幻想です。
const user = { name: "taro", token: "SECRET_TOKEN" };
localStorage.setItem("user", JSON.stringify(user));
JavaScriptこうしても、攻撃者側から見れば
const json = localStorage.getItem("user");
const user = JSON.parse(json);
console.log(user.token); // "SECRET_TOKEN"
JavaScriptと、普通に取り出せます。
JSON はあくまで「構造を文字列にするためのフォーマット」であって、
暗号化でもマスクでもありません。
「JSON にしているから大丈夫」は、
セキュリティ的には 0 点だと思ってください。
「何を JSON に入れているか」をちゃんと見る
JSON でまとめて保存するとき、
つい「ユーザー情報一式」をそのまま突っ込みがちです。
const user = {
id: 1,
name: "taro",
email: "taro@example.com",
token: "SECRET_TOKEN",
};
localStorage.setItem("user", JSON.stringify(user));
JavaScriptこのときに大事なのは、
「このオブジェクトの中に、localStorage に置くべきでないものが混ざっていないか」
をちゃんと見ることです。
例えば、
id や name はまだいいとしても、token は本当にここに入れていいのか?
という問いを自分に投げる習慣をつけてください。
物理的な「端末の共有」という観点も忘れない
同じブラウザを複数人が使うケース
家族で PC を共有している
ネットカフェの PC を使っている
会社の共用端末を使っている
こういう場合、
localStorage の中身は「そのブラウザを使う人全員から見える」状態になります。
開発者ツールを開いて Application タブを見れば、
localStorage の中身は簡単に覗けます。
つまり、
「その端末を使う別の人が、localStorage の中身を見ても困らないか?」
という視点も必要です。
例えば、
テーマ設定
言語設定
UI の表示状態
このあたりは見られても大きな問題にはなりません。
一方で、
メールアドレス
本名
住所
電話番号
などをそのまま保存しておくと、
「同じ端末を使う別の人から丸見え」になります。
「端末を信頼できるか?」という問い
セキュリティの世界ではよく、
「クライアント(ユーザーの端末)は信頼しない」
という前提で考えます。
localStorage / sessionStorage は、
まさに「クライアント側のストレージ」です。
だから、
「この情報を localStorage に置くということは、
この端末を使う誰かに見られてもいいと認めることだ」
というくらいの感覚でいてください。
セキュリティを意識したストレージ利用の考え方
「何を保存しないか」を先に決める
ストレージを使うとき、
「何を保存するか」より先に、
「何は絶対に保存しないか」を決める のが大事です。
例えば、こんな線引きができます。
保存しない(サーバー側だけで扱う)
パスワード
本物のアクセストークン / リフレッシュトークン
クレジットカード情報
マイナンバーなどの機微情報
保存してもよい(ただし必要最小限)
テーマ、言語などの UI 設定
「前回開いていたタブ」などの軽い状態
TODO やメモなど、ユーザーが自分で書いた内容(サービスの性質による)
この線引きを、
「なんとなく」ではなく、
言葉にしてチームで共有できるレベル まで持っていくのが、プロの設計です。
「消すタイミング」もセットで考える
セキュリティ的には、
「長く残っているほどリスクが高まる」
という側面があります。
なので、
ログアウト時に何を消すか
一定期間使われていないデータを消すか
一時的な情報は sessionStorage にして、タブを閉じたら消えるようにするか
といった「消す設計」も重要です。
例えば、ログイン状態を localStorage にフラグで持つとしても、
function logout() {
localStorage.removeItem("loggedIn");
// 必要なら他の関連データも消す
}
JavaScriptのように、
「ログアウトしたらちゃんと消す」
という動きを組み込んでおくことが大事です。
初心者として本当に覚えておいてほしいこと
最後に、あなたの頭の中に強く残しておいてほしいポイントをまとめます。
ストレージ(localStorage / sessionStorage)は「安全な金庫」ではなく「ただのメモ帳」
JavaScript から自由に読める=XSS が起きたら中身は全部見られる
パスワードや本物のトークンなど「盗まれたら終わるもの」は絶対に置かない
JSON にしても安全にはならない(構造が文字列になっているだけ)
同じブラウザを使う別の人からも、開発者ツール経由で中身は見える
「何を保存しないか」「いつ消すか」を設計として決める
技術的なテクニックより前に、
「ストレージは信用しすぎてはいけない場所だ」
という感覚を持てるかどうかが、セキュリティのスタートラインです。
そこさえブレなければ、
あとは「じゃあ何をどこに置くべきか?」を一緒に積み上げていけます。
