utsuroi jwt labsLab 01 / 5 — Practitioner
01

JWT alg=none による権限昇格

JWT alg=none allows arbitrary payload modification

うつろい EC は JWT ベースの認証を採用。ログイン後に HS256 で署名された JWT を発行し、API リクエストに Authorization: Bearer ... として添付する。

サーバ側のコードに重大なバグ:JWT 内の alg ヘッダ値をそのまま採用している。alg=none が指定されたトークンに対しては署名検証をスキップしてしまう。

あなたは一般会員(role: "user")として JWT を発行された状態。alg=none 攻撃で role: "admin" に書き換えて、管理者権限を獲得してください。

Header (base64 decoded)
Payload (base64 decoded)
Signature

① ヘッダを書き換え

alg を変更してみてください。

② ペイロードを書き換え

role を user から admin へ。

③ 署名

alg=none の場合は署名は空文字列でよい。それ以外の alg では正しい署名鍵が必要。

④ サーバへリクエスト送信

サーバの検証ロジック
jwt.verify(token, SECRET) — alg を JWT 内の値に従う
サーバ応答
(まだリクエストを送っていません)
脆弱な実装(Node.js)
// 危険:期待する alg を指定していない
const decoded = jwt.verify(token, SECRET);
// → alg=none も成立してしまう

// 古いライブラリではこれがデフォルト挙動。最新版では明示的に算法指定が必要(セキュアバイデフォルト化)。
攻撃の手順
1. ヘッダ {"alg":"HS256",...} → {"alg":"none",...} に変更
2. ペイロードの role: "user" → "admin"
3. 署名を空文字列に
4. base64url(header) + "." + base64url(payload) + "." を送信
5. サーバ: alg=none を見て検証スキップ → ペイロードを信頼 → 管理者として処理
正解(ネタバレ)
  1. ヘッダを {"alg":"none","typ":"JWT"} に変更
  2. ペイロードの "role":"user""role":"admin" に変更
  3. 署名フィールドは空のまま
  4. 「トークンを偽造」 → 「偽造トークンで /api/account を呼ぶ」
  5. サーバが alg=none を信用して検証スキップ → admin として処理される