コンテンツにスキップ

JWT のセキュリティベストプラクティス|alg none 攻撃 / 有効期限 / 署名検証

カテゴリ:認証・セキュリティ

JWT (JSON Web Token) はモダンな Web API の認証でデファクトスタンダードですが、仕様を誤解したまま実装すると簡単に脆弱性を生みます。本記事では実際に多く見られる JWT の誤用パターンと、それを避けるためのベストプラクティスを解説します。

JWT の構造おさらい

JWT は 3 つの Base64URL エンコード文字列をドットで連結した形式です。

eyJhbGci...    .   eyJzdWIi...     .    SflKxwRJSM...
   header              payload                signature
  • header: 署名アルゴリズム (alg) とトークン種別 (typ)
  • payload: クレーム (sub / iss / aud / exp / iat / ...) の JSON オブジェクト
  • signature: header と payload を対象にした HMAC / RSA / ECDSA 署名

JWT の中身は DevLab の JWT デコーダ で確認できます。Base64URL はエンコードであって 暗号化ではない ので、payload の中身はサーバで署名検証しなくても誰でも読めることを忘れずに。

脅威 1: alg=none 攻撃

JWT 仕様には "alg": "none" という「署名なし」のアルゴリズム指定が存在します。攻撃者がこれを利用して {"alg":"none"} のヘッダで payload を書き換え、ライブラリがそのまま受け入れると 任意のユーザーに成りすませる 致命的な脆弱性になります。

対策:

  • 検証時に許可するアルゴリズムを 明示的にホワイトリスト 指定する
  • jwt.verify(token, secret, { algorithms: ['HS256'] }) のように配列で渡す
  • 2015 年頃のライブラリは脆弱だったが現在の主要ライブラリは対策済み。ただし自作しない限り最新版を使うこと
// ✗ 悪い例 (アルゴリズム未指定 = ライブラリが alg ヘッダを信頼)
jwt.verify(token, secret);

// ✓ 良い例 (アルゴリズムを固定)
jwt.verify(token, secret, { algorithms: ['HS256'] });

脅威 2: 鍵混同攻撃 (key confusion)

RSA 公開鍵を持っている攻撃者が、アルゴリズムを RS256 から HS256 に変える ことで公開鍵を「秘密鍵」として扱わせる攻撃です。JWT ライブラリが alg を信頼して検証関数を選ぶと、公開鍵で HMAC 署名された偽トークンが通ってしまいます。

対策: アルゴリズムは必ず検証側で固定する (脅威 1 と同じ対策)。さらに、鍵の種類も明示的に区別する:

  • HS256 なら Buffer で渡す
  • RS256 なら PEM フォーマットの公開鍵で渡す

脅威 3: 有効期限の未検証 / 無期限トークン

JWT の exp クレームは有効期限を示す UNIX 秒ですが、検証時に無視されているケース がよくあります。一度発行されたトークンが永久に使えると、漏洩時に被害が止まりません。

対策:

  • 発行時に exp を短く設定 (アクセストークンは 15 分〜1 時間が目安)
  • 検証時に必ず exp をチェック (主要ライブラリは自動でやる)
  • 長期セッションが必要ならリフレッシュトークンパターンを使う (アクセストークン短命 + リフレッシュトークン長命 + サーバサイド失効リスト)

脅威 4: JWT に機密情報を入れる

JWT の payload はただの Base64 エンコードで、誰でも復号できます。それを知らずに パスワードやクレジットカード番号を payload に入れる 実装が後を絶ちません。

対策:

  • payload には「このユーザーである」という最小限の識別情報だけ入れる (sub / user_id / role)
  • 機密情報はサーバサイドのデータベースに置き、JWT からは user_id で引く
  • どうしても機密情報を JWT で送る必要がある場合は JWE (暗号化版 JWT) を使う

脅威 5: 失効 (logout) ができない

JWT はステートレスで発行すると取り消せません。ユーザーがログアウトしても、サーバ側にトークン情報がないため「有効期限まで使えてしまう」。パスワード変更しても発行済みの JWT は生き続けます。

対策:

  • 短い exp (15 分以下) で被害ウィンドウを最小化
  • ログアウト時はサーバ側の 失効リスト (denylist)jti (JWT ID) を登録して、検証時に照合
  • 重大なイベント (パスワード変更・権限変更) 時は token_version をユーザーレコードに保存して、検証時に一致を確認

脅威 6: 弱いシークレット

HS256 のシークレットが短すぎると、総当たりで解読されます。特に "secret" "password123" といった文字列は即死です。

対策:

  • HS256 は少なくとも 256 ビット (32 バイト) のランダム値を使う
  • 生成は openssl rand -base64 32パスワード生成ツール
  • シークレットは絶対に Git にコミットしない。環境変数・Secrets Manager で管理

ベストプラクティスのまとめ

  1. 検証側でアルゴリズムを固定 (algorithms: ['HS256'])
  2. HS256 のシークレットは 256 ビット以上、RS256 なら 2048 ビット以上の RSA
  3. アクセストークンの exp は 15 分〜1 時間
  4. リフレッシュトークンパターンで長期セッションを実現
  5. payload には機密情報を入れない (Base64 は暗号化ではない)
  6. ログアウト時は失効リストに jti を登録
  7. シークレットは環境変数・Secrets Manager で管理、コミット厳禁
  8. クライアント側では JWT を localStorage ではなく HttpOnly Cookie に格納 (XSS 対策)

デバッグに役立つツール

まとめ

JWT は正しく使えば便利な認証トークンですが、仕様の罠と攻撃パターンを知らないと本番システムに脆弱性を仕込むことになります。本記事で示した 6 つの脅威と対策を押さえ、JWT ライブラリの最新版を使うことが基本です。定期的に実装を見直し、セキュリティアドバイザリを追うことをおすすめします。

📚 関連記事

PNG vs WebP vs AVIF|画像フォーマットの選び方と変換方法

PNG / JPEG / WebP / AVIF の特徴・用途・ブラウザ対応状況を比較。picture 要素での出し分け、DevLab の画像フォーマット変換ツールの使い方も解説。

2026-04-18

Whois でドメイン情報を調べる方法|有効期限・ネームサーバー・登録者

Whois でわかること (登録者・有効期限・レジストラ・NS)、GDPR によるプライバシー保護の影響、ドメイン管理の実務的な使い方を解説。

2026-04-18

HTTP ステータスコード完全ガイド|よくあるエラーの原因と対処法

開発者が頻出する HTTP ステータスコード (200/301/302/400/401/403/404/413/422/429/500/502/503/504) の意味・原因・対処法を解説。301 vs 302 の SEO 影響、400 vs 422 の使い分けも。

2026-04-18

cURL コマンドを JavaScript fetch・Python requests に変換する方法|DevTools 連携

Chrome DevTools の Copy as cURL を fetch / axios / Python requests / PHP cURL / Go net/http に変換する手順を解説。主要 cURL オプション (-X / -H / -d / -F / -u / -b / -L) の変換パターン、認証トークンの扱い、注意点まで。

2026-04-16

Cookie のセキュリティフラグ完全ガイド|Secure / HttpOnly / SameSite / __Host-

Cookie のセキュリティ属性 Secure / HttpOnly / SameSite (Strict/Lax/None) / __Host- __Secure- プレフィックス / 4096 バイト制限を解説。CSRF / XSS / セッションハイジャック対策と、Laravel / Express の実装例。

2026-04-16

ExcelでCSVを正しく開く・保存する方法|文字化けしないUTF-8 BOM対応

ExcelでCSVを開くと文字化けする原因と解決策。UTF-8 BOM付きCSVの作り方、Excelインポート手順、PHPとPythonでのBOM付きCSV出力コード例。macOS版Excelの注意点も解説。

2026-04-14