JWT ベースの認証の影: 利便性の裏に隠れた致命的な脅威

概要

現代の Web アプリケーションとモバイルアプリのスタンダードとして定着した JWT は stateless 認証の利便性を提供するが、安全でない方法で運用および管理される場合、認証システム全体を崩壊させることがある単一障害点(Single Point of Failure)となることもある。本記事では JWT の概念と認証方式を紹介した後、CVE 事例を中心に主要な脆弱性を解析し、これを予防および緩和するための実質的な防御戦略を提示する。

 

JSON Web Token (JWT)

JWT は Web 標準(RFC 7519)であり、JSON オブジェクトを使用して二つのエンティティ間で情報を安全に送信する軽量かつ自己完結的(compact and self-contained)な方式である。このトークンはすべての必須情報を自らに保持しており、サーバーでデータベースを照会することなくトークンだけでユーザー認証および権限確認が可能である。また、ステートレス(stateless)な構造によりサーバー側のセッションの保存および同期の負担を軽減し、HTTP ヘッダーや URL パラメーターで簡単に伝達されるため、分散環境での拡張や伝達が容易であるという点から、JWT は現代の Web/Microservices 環境の主要な認証方式として定着した。

 

1) JWT の構造および構成要素

JWT は Base64Url でエンコードされた三つの部分(Header、Payload、Signature)がピリオド(.)で区切られ、結合された形式で構成される。

[図1] JWT 構造

 

1. Header(ヘッダー):メタ情報

ヘッダーはトークンのメタ情報を保持している JSON オブジェクトを Base64Url でエンコードした部分である。必須で typ(Type、一般的に JWT)および alg(Algorithm、署名に使用された暗号化アルゴリズム、例: HS256、RS256)のクレームを含む。

{
  "alg": "HS256",  // 署名アルゴリズム
  "typ": "JWT"     // トークンタイプ
}

 

2. Payload (ペイロード) : クレーム(Claim)

ペイロードには、送信する認証情報、権限情報、その他の属性情報が JSON オブジェクト形式で含まれ、これをクレーム(Claim)と呼ぶ。ペイロードもまた、ヘッダーと同様に Base64Url でエンコードされる。

  • クレームの種類クレーム
    クレームの種類クレームは役割によって Registered (標準定義)、Public (公開)、Private (プライベート)の3種類に分かれる。Registered Claims には、トークンの有効期限(exp)、発行時刻(iat)、発行者(iss)、受信者(aud)等、トークンの有効性検証に活用される標準フィールドを含む。
  • セキュリティの注意点
    ヘッダーとペイロードは暗号化ではなく単純なエンコードであるため、ペイロードを確保すると容易にデコードして内容を把握することができる。そのため、ペイロードには電子メール、決済情報等、センシティブな個人識別情報(PII)を含めてはならない。
{
  "sub": "user123",           // ユーザー ID
  "name": "John Doe",         // ユーザー名
  "role": "admin",            // 権限
  "iat": 1516239022,          // 発行時間
  "exp": 1516242622           // 有効期限
}

 

3. Signature (署名) : 完全性保証

署名は、トークンの完全性(Integrity)および信頼性(Authenticity)を保証するキーハイブ要素である。署名は、エンコードされた Header と Payload、そしてサーバーが保管する Secret Key(HS256) または Private Key(RS256)を結合し、指定されたアルゴリズムに従った暗号学的署名演算で計算される。サーバーは署名を再計算して受信された署名と一致するかどうかを確認し、これによってトークンの改ざんの有無を判断する。秘密署名キーを知らない攻撃者は、有効な署名を生成することができない。

HMACSHA256(
  base64UrlEncode(header) + "." + base64UrlEncode(payload),
  SECRET_KEY
)

 

2) セッションベースの認証方式と JWT 認証方式の比較

セッションベースの認証方式と JWT 認証方式の違いは、[図2]の図式比較を通して確認できる。

[図2] セッションベースの認証方式と JWT 認証方式のプロセス比較

 

セッションベースの認証方式

セッションベースの認証方式は主に4つの欠点を抱えている。

  • サーバーがセッション状態を直接管理しなければならない Stateful 構造
  • サーバーの水平拡張時にセッション共有(共同セッションストア、Sticky Session 等)が必要
  • セッションストレージ(DB、Redis 等)に対する追加負荷および運用コスト発生
  • 中央セッションストレージに依存するためマイクロサービスおよび分散アーキテクチャにおいて柔軟性が低下する可能性がある

 

JWT 認証方式

それに対し、JWT 認証方式はセッションベースの認証の欠点をある程度解消する。

  • Stateless 構造で、別途のセッションストレージなしに署名検証のみで基本認証が可能
  • サーバー/インスタンス間でセッションの同期が必要なく、水平拡張に有利
  • 各サービスがトークンを直接検証できるため、マイクロサービスアーキテクチャに親和的
  • トークンにユーザー識別子、権限、期限などを含め、サーバー状態への依存度を減らす

 

主要 JWT セキュリティ脆弱性

JWT の脆弱性は主に、署名検証ロジックの実装エラーや、ユーザーが操作できる Header パラメータをサーバーが無分別に信頼する時に発生する。JWT の核心の利点である Stateless 特性は、運用設計が不十分な場合、逆に致命的な弱点として作用することがある。伝統的なセッション方式はサーバーでセッションを削除する場合、強制ログアウトが即時反映されるが、JWT はクライアントが保持するため、サーバーがトークンを即時回収するのが困難で、別途の取り消しメカニズムがない場合、期限時点まで有効な場合がある。特に、社員の権限が変更やアカウントが非アクティブ化されても、以前に発行された JWT が期限前であれば API アクセスが可能になる場合がある。アカウントの奪取を検知し、パスワードを再設定しても攻撃者がすでに確保した JWT は、期限前まで有効なままとなる場合がある。

署名キーが流出すると、攻撃者は任意のユーザーに成りすますや、権限を昇級させたトークンを生成することができる。実際に流出した署名キーを利用して認証トークンを偽造し、大規模なデータ流出が発生した事例が報告された。このように、偽造トークンが署名検証を通過すると、サーバーおよび検知システムはこれを正常なリクエストとして認識し、処理することができるため、検知が遅延する状況が発生する場合がある。

 

1) 署名の完全性検証回避脆弱性

1. HS/RS アルゴリズム混同脆弱性(CVE-2015-9235)

jsonwebtoken Node.js 4.2.2 未満バージョンは、非対称アルゴリズム(RS/ES 系列)で検証しなければならない状況でも、対称アルゴリズム(HS 系列)で署名されたトークンを受け入れるアルゴリズム混同問題が存在する。攻撃者は、サーバーが検証に使用する公開キーを HMAC 秘密キーのように悪用し、任意のペイロードでトークンを偽造して、認証をバイパスや、権限を昇級させることができる。

2. alg=none 許可脆弱性(CVE-2021-22160/CVE-2022-23540/CVE-2025-61152)

一部の実装は、alg: “none”が含まれているトークンに対して署名検証を実行せず、検証オプション未指定時に none を事実上許容する方式で動作し、署名検証の回避を誘発する。Apache Pulsar は alg=none の時、署名を検証しない問題が報告され、jsonwebtoken は jwt.verify()でアルゴリズムを明示しない時、none をデフォルト処理で検証の回避が可能になり、python-jose は alg=none のトークンを署名検証なしに許可する問題が報告された。

3. JWT クレーム改ざん脆弱性(CVE-2022-39227)

python-jwt 3.3.4 未満バージョンは、JWS Compact シリアライゼーションと JWS JSON シリアライゼーションの処理過程の不一致により、署名検証に通過した値とアプリケーションが実際に使用するクレームが異なる場合がある。攻撃者は、秘密キーを知らなくても既存のトークンの署名を再利用する方式でクレームを改ざんし、認証を回避することができ、当該脆弱性は CVSS 9.1 点(Critical)で評価された。

 

2) アルゴリズム混同攻撃

1. json-web-token ライブラリの脆弱性(CVE-2023-48238)

Node.js 用 json-web-token 3.1.1 未満バージョンは、検証に使用するアルゴリズムを JWT ヘッダーの alg フィールドから抽出する設計欠陥がある。サーバーが RS256 を使用中で、攻撃者が公開キーを確保した場合、攻撃者は alg を HS256 に設定し、公開キーを HMAC キーのように使用させることで、秘密キーなしでもトークンを偽造することができる。

2. cjwt ライブラリの脆弱性(CVE-2024-54150)

C ベースの JWT ライブラリ cjwt の v2.2.0 は、トークン検証プロセスにおいて署名方式(HMAC vs RS/EC/PS)を厳格に区分できず、アルゴリズム混同(algorithm confusion)が発生する可能性がある。これにより、検証ロジックがトークンの alg とキータイプを安全に強制しない構成では、攻撃者が公開鍵を HMAC キーのように扱わせることで、秘密キーなしでも偽造トークンの検証を通過させるように誘導できる。本脆弱性は v2.3.0 で修正された。

 

3) キー検索メソッドパラメータ注入攻撃

1. kid パラメータのパス遍歴および SQL インジェクション

サーバーが kid 値をファイルパスやデータベース検索クエリに直接接続して使用する場合、攻撃者はパス遍歴文字列や SQL 文を注入し、任意のキーを選択させたり、キー検索ロジックを攪乱したりすることができる。結果的に、誤ったキーで検証が行われるか、キーの保存所情報の漏洩につながる可能性がある。

 

4) キー管理失敗の脆弱性

1. ハードコーディングされた秘密キー (CVE-2025-7079 / CVE-2025-6950)

署名キーがコードやファームウェアにハードコーディングされている場合、攻撃者はその値を確保して任意の JWT を偽造し、認証をバイパスすることができる。CVE-2025-7079 は bluebell-plus の jwt.go ファイルに「bluebell-plus」文字列がハードコーディングされた事例であり、CVE-2025-6950 は Moxa ネットワークセキュリティ機器およびルーターで JWT 署名用ハードコーディングキー使用が報告された事例である。

2. iss クレーム形式違反 (CVE-2025-30144)

fast-jwt 5.0.6 未満には RFC 7519 の観点から文字列である必要がある iss クレームに文字列配列を許容する検証欠陥が存在する。攻撃者は正常な発行者と不正な発行者を混合させた iss 配列を構成し、検証ロジックを回避することができる。

3. 署名キーのローテーションおよび廃棄失敗によるインサイダー悪用

組織が JWT 署名キーを長期間運用し、担当者の変更や権限調整の際にキーのローテーションまたは廃棄手続きを実行しないと、流出したキーで有効な JWT が生成され続ける可能性がある。署名が正常に検証されると1つのサーバーと監視は、これを正常なトラフィックと誤認することがあり、検知が遅延して事故が外部からの通報や調査後に識別される状況が発生することもある。

 

検知および防御戦略

内部キーの流出を含むすべての JWT 攻撃ベクターに対応するため、サーバー側の検証ロジックを強化し、リアルタイム侵害検知システムの構築が必要である。

 

1) 安全なキー管理システムの構築および HS256 代替戦略

1. ハードウェアセキュリティモジュール(HSM)またはクラウド KMS を活用

署名キー資料をアプリケーションサーバーのファイルシステムやメモリから隔離することが、内部者脅威への対応の鍵である。署名キー(秘密キー/プライベートキー)は HSM(Hardware Security Module) またはクラウドベース KMS(Key Management Service) に保存し、アプリケーションサーバーはキー値を直接取り扱わず、署名演算 API を呼び出す方式で使用する必要がある。これは、内部者がサーバーにアクセスしてもキー資料の取得を物理的に遮断する。

2. 非対称キー(RS256)への移行および Key Rotation

内部者脅威とキー露出リスクを低下させるため、対称キー(HS256)の単一共有構造よりもプライベートキー・パブリックキー構造の非対称キー(RS256)の使用を優先して考慮しなければならない。プライベートキーは HSM/KMS 内部に保管され、パブリックキーは外部に配布される可能性があるが、プライベートキーの機密性が維持されている限り、攻撃者が有効なトークンを偽造することはできない。また、侵害される可能性を前提にキーの寿命と交換周期を定義し、定期的にキーをローテーションおよび廃棄する運用手順を整備する必要がある。

 

2) サーバー側の厳格なトークン検証の実装

JWT ライブラリを使用しても、開発者は標準スペックで許可されているすべての潜在的リスクを明示的に遮断する必要がある。

1. アルゴリズムホワイトリストの強制化

JWT 検証時、サーバーが許可するアルゴリズム(例: RS256)をライブラリに明示的に固定する必要がある。これは、alg=none のような安全でないアルゴリズムの受容を遮断し、アルゴリズム混同攻撃の試みを無力化する。

2. Critical Claims에 대한 Strict Validation2. Critical Claims に対する Strict Validation

exp(有効期限)、iss(発行者)、aud(受信者)等、標準クレームに対する検証を漏れなく実行する必要がある。Access Token を受信する際、exp の有効性検証によって期限切れトークンの使用を遮断しなければならない。

3. キー参照パラメータの防御

kid、jku、jwk のような動的キー参照メカニズムは、インジェクション攻撃のベクターを提供するため、使用を避ける必要がある。避けられない場合は使用する必要があるが、kid 値に対して Path Traversal パターンおよび SQL Injection パターンを含んだ強力な入力フィルタリング(ホワイトリストベース)を適用することを勧告する。

 

3) トークンの寿命管理および無効化戦略

1. Access Token の寿命管理

Access Token は、窃取された場合の被害範囲(Blast Radius)を最小化するために数分以内の短い寿命(exp)で発行する必要がある。長期的なセッションの維持は Refresh Token で分離し、Refresh Token には再利用防止のためのローテーション(Rotation)と一度きりの使用のようなポリシーを適用する構成が推奨される。

2. リアルタイムトークン無効化(Revocation)システム

キー流出や強制ログアウト発生時、即時のトークン無効化のため中央集権式 Revocation List を構築する。各 API リクエストはトークンの jti クレームを基に Revocation List を照会し、一覧に存在する場合はリクエストを遮断する。Revocation List の項目はトークンの有効期限(exp)まで TTL によって自動で期限切れとなるように管理する。

 

4) 侵害検知およびモニタリング体系

1. 詳細ロギングおよび SIEM 統合

JWT 検証失敗イベント(Invalid Signature、Algorithm Mismatch、Claim Errors 等)を詳細に記録し、これを中央集権式 SIEM システムに統合する。

2. 異常兆候自動検知システムの構築

短期間に同じトークンの過度な API 呼び出し(Replay Attack の試み)や、地理的に異常なアクセス分布、またはトークンの有効期限(exp)が異常に長いトークンが流入する場合など、異常兆候を検知し、即時の警報を発生させてさらなる被害を防ぐようにする。

 

結論

JWT ベースの認証システムのセキュリティ失敗は、企業のコア資産に対する広範な侵害へと繋がる可能性がある。特に署名キーの管理失敗は、認証システム全般を無力化する高リスクな単一障害地点へと昇華する可能性がある。そのため、署名キーを HSM または KMS 内部に隔離し、非対称キーベース(RS256)の転換とキーローテーションポリシーを最優先課題として設定する必要がある。同時に、アルゴリズム固定、コアクレーム検証、キー参照入力防御を含んだ厳格な検証ロジックを実装し、攻撃の成功可能性を事前に低下させなければならない。最後に、ログベースの検知と異常兆候の自動化を結合し、侵害の兆候を早期に識別して被害を最小限に抑える運用システムの構築を推奨する。

 

出所

 

関連 IOC および詳細な解析情報は、AhnLab の次世代脅威インテリジェンスプラットフォーム 「AhnLab TIP」 サブスクリプションサービスを通して確認できる。

Categories: マルウェア