Hello there, ('ω')ノ
🧩 攻撃の流れ
正規ユーザーでJWTを取得 通常どおりログインし、JWTトークンを手に入れます。
ヘッダの
alg
を改ざん JWTヘッダを Base64URL デコードして:
{"alg":"HS256","typ":"JWT"}
を以下のように書き換え:
{"alg":"none","typ":"JWT"}
ペイロードを改ざん 例えば以下のように、
sub
(ユーザー名)やrole
(役割)を管理者に変更します。署名部分を削除
alg=none
にすると署名の検証が不要になります。トークンは、
<base64ヘッダ>.<base64ペイロード>.
という末尾にドットだけの形式にします。
- 改ざんトークンを送信 脆弱なサーバーに送ると、署名検証せずにトークンを受け入れ、改ざんされたユーザーとして認識される可能性があります。
✅ 実際のラボ操作(PortSwigger の手順例)
- Lab: JWT authentication bypass via flawed signature verification では、ヘッダ内の
alg
をnone
に変更し、署名を削除して/admin
へリクエスト送信するだけで攻撃が成功します。
⚠️ こんなケースで要注意!
alg=none
自体をきちんと禁止していない- サーバー側がヘッダの
alg
値を 信頼している - ライブラリの decode() 関数だけ使って verify() を呼んでいない
🛡 対策
対策 | 説明 |
---|---|
alg=none を拒否 | 明示的にホワイトリストで受け入れアルゴリズム(HS256, RS256 等)を指定 |
署名検証は常に必要 | decode() の前に経由する verify() を使用。単なるデコードではなく、改ざん検知を徹底 |
ライブラリ設定を確認 | none を無効化する設定が存在する場合は必ず ON に |
トークン検証をログ監査 | 不正なtokenが来た場合に警告やログに記録して検知しやすく |
🔚 まとめ
alg=none
を正式にサポートする実装の甘さを突く、JWTにおける典型的かつ重大な脆弱性です。現代的な対応としては:
- アルゴリズム許可リスト
- 常に署名検証
- decode() の濫用禁止
が鍵です。
Best regards, (^^ゞ