【入門編】JWTの安全なストレージ:LocalStorage vs HttpOnly Cookie – アプリケーションセキュリティ & 安全な開発防御ガイド

「JWTはどこに置くのが正解?」XSSとCookieの攻防を、家の鍵に例えて解説します

こんにちは。セキュリティの世界へようこそ。
システム開発をしていると、「JWT(JSON Web Token)」という言葉、一度は耳にしますよね。ログインした後の「通行証」のようなものですが、この大切な通行証をどこに保管するかで、あなたのシステムのセキュリティ強度は天と地ほど変わります。

今日は、多くのエンジニアが悩む「LocalStorage vs HttpOnly Cookie」の決着を、身近な防犯に例えて紐解いていきましょう。

1. なぜ「LocalStorage」に置くと危ないのか?

まずは、やってはいけない例からお話しします。

LocalStorageは、ブラウザの中に用意された「ちょっとしたメモ帳」のような場所です。ここにJWTを置くと、JavaScriptというプログラミング言語から簡単に読み書きができます。

ここで「家の鍵」に例えてみましょう。

家の鍵を、玄関のドアのすぐ横にある「誰でも開けられる郵便受け」に置きっぱなしにしている状態を想像してください。
もし、あなたの家に悪意のある訪問者(XSS攻撃者)がやってきたらどうなるでしょう?

XSS(クロスサイトスクリプティング)とは、Webページに悪意のあるスクリプト(命令)を紛れ込ませる攻撃のことです。このスクリプトが実行されると、泥棒はあなたの郵便受け(LocalStorage)の中身を、一瞬でごっそり盗み出すことができます。

一度盗まれると、犯人はあなたの「通行証」を手にしているわけですから、あなたになりすましてサイトを自由に操作できてしまいます。これがLocalStorageの最大のリスクです。

2. 「HttpOnly Cookie」という強固な金庫

そこで登場するのが「HttpOnly Cookie」です。これは、Cookieという仕組みに「ブラウザ専用の金庫」のような制限をかける設定のことです。

「HttpOnly」という属性を付けると、JavaScriptからはその中身に一切触れられなくなります。

これなら、もしWebサイトにXSSの穴があったとしても、泥棒は「鍵(JWT)」を見つけることができません。JavaScriptが「鍵を見せて!」と命令しても、ブラウザが「それは教えられないよ」とガードしてくれるからです。

3. 実践!安全なCookieの設定方法

では、サーバー側でJWTを発行するとき、具体的にどう設定すべきかを見ていきましょう。ただCookieに保存するだけでは不十分です。以下の「3つの盾」を必ず組み合わせます。

設定のサンプルコード(Node.js/Expressの例)

res.cookie(‘accessToken’, jwtToken, {
httpOnly: true, // 【重要】JavaScriptからのアクセスを禁止(XSS対策)
secure: true, // 【重要】HTTPS通信時のみ送信を許可(盗聴対策)
sameSite: ‘lax’, // 【重要】他のサイトからの不正なリクエストをブロック(CSRF対策)
maxAge: 3600000 // 有効期限を1時間に設定
});

3つの盾の解説

1. HttpOnly: 前述の通り、JavaScriptからの持ち出しを禁止します。
2. Secure: 通信を暗号化(HTTPS)しない限り、Cookieを送信しません。鍵を渡す時に「封筒」に入れずに渡すのは危険ですよね。これは、鍵を渡すルートを完全に暗号化されたトンネルにする設定です。
3. SameSite: 別のサイトからあなたのサイトへ向けて「勝手に鍵を使って何かして!」という指示(CSRF攻撃)を飛ばされるのを防ぎます。

4. でも、気をつけることはあるの?

ここまで読むと「HttpOnly Cookieさえあれば完璧!」と思うかもしれませんが、セキュリティに「絶対」はありません。

HttpOnly Cookieを使っていても、CSRF(クロスサイトリクエストフォージェリ)という別の攻撃手法には注意が必要です。これは、別のサイトを経由して「あなたのブラウザに、あなたのサイトへ勝手にリクエストを送らせる」攻撃です。

これに対しても、上記の`SameSite: ‘lax’`(あるいは厳格な`’strict’`)を設定することで、かなりの確率で防ぐことができます。

まとめ:今日からできる一歩

セキュリティ対策は、一度にすべてを完璧にする必要はありません。まずは以下のステップで進めてみましょう。

  • ステップ1: JWTをLocalStorageに保存していないか確認する。
  • ステップ2: サーバー側のCookie発行設定に `httpOnly`, `secure`, `sameSite` が揃っているか確認する。
  • ステップ3: 開発環境(ローカル)でもHTTPS環境を用意し、本番と近い設定で動かしてみる。

「便利だから」という理由だけでLocalStorageに頼るのは、もう卒業しましょう。あなたのユーザーの大切な情報を守るために、ブラウザの強力な防犯機能を正しく使ってあげてくださいね。

一歩ずつ、安全なアプリケーションを作っていきましょう!応援しています。

コメント

タイトルとURLをコピーしました