JWTの「鍵なし」攻撃?泥棒が勝手に合鍵を作る手口と、それを防ぐ鉄壁の守り方
こんにちは。日々、システムの脆弱性と戦っているセキュリティエンジニアです。
皆さんは「JWT(JSON Web Token)」という言葉を聞いたことがありますか?Webサイトにログインしたとき、「あなたは確かに本人ですよ」と証明するための「デジタル通行証」のようなものです。
この通行証、実はとっても便利なんですが、作り方を間違えると「泥棒が自分で合鍵を作って侵入できてしまう」という致命的な穴が生まれてしまいます。今日は、そんなJWTの「noneアルゴリズム攻撃」という悪夢を、身近な例えで解説していきますね。
—
1. なぜ「none」が危険なのか?(家の鍵で例えると)
JWTは、通常「サーバーだけが知っている秘密の暗号」を使って、通行証に封印(署名)をします。
- 正常な状態: サーバーが封印した通行証を渡す。受け取った人は、封印が剥がれていなければ「これは本物だ」と信じる。
- 「none」攻撃: 悪いやつが通行証の封印部分を「none(=なし)」という文字に書き換える。「この通行証に封印は必要ありません」とサーバーに嘘をつくんです。
もし、サーバーが「お、noneって書いてあるな。じゃあ署名のチェックはしなくていいや」と油断してしまったらどうなるでしょう? 誰でも自由に中身を書き換えた「偽の通行証」を作って、なりすまし放題になってしまいます。
これが、JWTにおける「noneアルゴリズム攻撃」の正体です。
—
2. ライブラリを信じすぎるな!「設定の落とし穴」
多くの開発者は便利なJWTライブラリを使っています。しかし、ここが盲点なんです。
多くのライブラリは、開発者が「柔軟に使えるように」という配慮から、デフォルトで「noneアルゴリズム(署名なし)」を受け入れる設定になっていることがあります。これが、現代のWeb開発における最大の罠の一つです。
「ライブラリがよしなにやってくれるだろう」という思い込みこそが、最も危険なセキュリティホールを生みます。
—
3. 実践!鉄壁の守り方を学ぼう
では、どうやってこの攻撃を防げばいいのでしょうか?
対策は非常にシンプルです。「例外を許さないこと」。
① アルゴリズムを明示的に指定する
ライブラリの検証関数を呼ぶ際、「アルゴリズムは必ずこれを使え!」と固定してしまいましょう。
// 悪い例:受け取ったJWTのヘッダーを鵜呑みにしている
jwt.verify(token, secretKey);
// 良い例:アルゴリズムを明示的に強制する
// 「HS256(秘密鍵による署名)」以外は絶対に認めないという強い意思表示です
jwt.verify(token, secretKey, { algorithms: [‘HS256’] });
② 公開鍵暗号(RS256)の活用を検討する
さらに強固にするなら、RS256という仕組みを使いましょう。
これは「鍵を2つに分ける」方法です。
- 秘密鍵: サーバーだけが持つ。「通行証を作る」ためのペン。
- 公開鍵: 誰でも見られる。「通行証が本物か確認する」ための虫眼鏡。
これなら、もし万が一サーバー以外の誰かに「虫眼鏡(公開鍵)」が渡ったとしても、通行証を偽造するための「ペン(秘密鍵)」は守られ続けます。
—
4. 今日からできる「守りの第一歩」
セキュリティ対策というと難しく聞こえますが、要は「相手(データ)を信じすぎないこと」に尽きます。
1. JWTのライブラリ設定を見直す: 今使っているコードで、algorithms の指定を忘れていないかチェックしてください。
2. 「none」を許可する設定を探す: もしそんな設定があれば、即座にオフ(無効化)にしましょう。
3. 定期的な棚卸し: プロジェクトで使っているライブラリが最新かどうかを確認してください。古いライブラリには、こうした「none攻撃」に対する脆弱性が潜んでいる可能性が高いです。
セキュリティは、一度設定して終わりではありません。泥棒は常に新しい鍵の壊し方を探しています。でも、こうして一つずつ仕組みを理解していけば、必ず強固な守りを作ることができます。
皆さんの書くコードが、今日も明日も安全であることを願っています。何か困ったことがあれば、いつでもまた聞きに来てくださいね!一歩ずつ、一緒に強くなっていきましょう。
コメント