何が起きるか

ここでは、利用者IDや権限などの情報に署名を付けて渡すJWTを扱います。ログインを確認した発行サーバーが作ったトークンを、利用者のブラウザなどがAPIへ提示し、APIは署名を検証してから中の情報を採用します。署名は内容の改変を検出するためのもので、内容を隠す暗号化とは異なります。 JWTにはJSONの内容とは別に、その内容に対応した署名データが付きます。APIは受け取った内容と署名の組が信頼する鍵で正しいかを検証するため、内容だけ変更したトークンは拒否できます。

説明用の例では、JWTのrole欄がuserの利用者を一般利用者、adminの利用者を管理者として扱うAPIを考えます。攻撃者が自分のトークンを読み、roleをadminへ変更し、ユーザー削除APIへのリクエストの認証用ヘッダーへ入れて送り直しても、発行者の鍵で作った署名とは一致しなくなります。ところがAPIがJSONを取り出すだけで署名を検証しないと、改変されたadminを信じ、攻撃者による他人のアカウント削除を許すおそれがあります。トークンの内容を読めることを、発行者が認めた内容である証拠と取り違える点が問題です。

正常ならどう動くか

発行サーバーは、本人確認後の利用者ID・役割・有効期限などをJWTへ入れ、管理する鍵で署名して利用者へ渡します。利用者がその文字列をAPIへの認証用ヘッダーなどへ入れて送ると、APIは設定済みの信頼する鍵と許可した方式で署名を検証します。

APIはJWTのissを信頼する発行者、audをこのAPIの受取先、expを現在時刻と照合します。用途は、たとえばログイン用とパスワード再設定用を区別するもので、専用の種類の欄や別の検証ルールを定め、ログイン用APIが再設定用トークンを採用しないように検査します。これらを通じて、このAPIで使ってよいトークンだと確認してから利用者IDと権限を読みます。署名が合っても別のAPI向けのトークンや期限切れなら拒否します。通常の署名付きJWTの内容は読めるため、内容の秘匿が必要な情報を署名だけで隠せるとは考えません。

不備と攻撃が成立する流れ

APIがJWT内のroleで管理者操作を判断する説明用の例です。攻撃者が自分のトークンのJSON部分を取り出し、roleをadminに変えて同じ形式へ戻し、ユーザー削除APIへ送ります。署名は元の内容に対応したままですが、APIがデコードだけで検証を省けば、改変した管理者権限を採用して削除処理へ進みます。

公開鍵で署名を検証する方式では、発行者だけが持つ秘密鍵で署名し、それと対になる公開鍵をAPIが使って検証します。攻撃者がトークン内の鍵URLへ自分の公開鍵を指定し、手元の秘密鍵で署名する例を考えます。APIが入力のURLから取得した公開鍵を無条件に信用すると、攻撃者の鍵の組としては署名検証に成功します。しかしその公開鍵が正規の発行者のものかは確認できておらず、攻撃者が書いた利用者IDまで信じてしまいます。別API向けのトークンを受け付ける問題は、署名以外の受取先や用途の検査が欠ける場合に起きます。

起こり得る被害と条件

他人の情報取得の例では、利用者IDを偽装したトークンを注文履歴APIへ送り、サーバーがそのIDの注文を返します。攻撃者はHTTPレスポンスから他人の配送先などを入手できます。

管理機能の例では、偽のroleを管理者として採用したAPIが、ユーザー削除や権限変更のリクエストを受け付けます。攻撃者が他人の利用者IDを削除対象に指定してアカウントを消したり、自分のアカウントへ管理者権限を保存させたりするおそれがあります。いずれも検証省略や鍵の誤選択など具体的な欠陥と、トークンの値を操作へ使う実装が条件です。JWTの形式自体が改変を正当化するわけではありません。

防ぎ方と、防げる理由

ライブラリの検証APIへ、受信側の設定で許可した署名方式と信頼する鍵を渡します。トークンの入力だけで任意の鍵URLを信用しないため、攻撃者が自分の鍵で作った署名を通せなくなります。署名不一致や未署名なら、利用者情報を使う前に拒否します。

issは信頼する発行者の識別子と、audはこのAPIを示す受取先と照合します。expは有効期限なので現在時刻が期限を過ぎていないか確認し、用途もこの操作に合うか検査します。これにより、正しい署名があっても別用途や期限切れのトークンを拒否できます。権限変更後も古いroleを信じ続けないよう、短い有効期間やサーバー側での失効・現在の権限の再確認を設計します。 失効を使う構成なら、APIは署名と期限の確認後にサーバーの失効情報も照合します。権限をDBから読み直す構成なら、JWT内の古いroleだけで許可せず、利用者IDに対応する現在の役割で判断します。

よくある誤解

Base64で読めても真正性の証明にはなりません。また、署名が正しくても古い権限が記載されたままなら、現在の権限とは異なり得ます。トークンの期限・失効と権限変更の扱いも設計する必要があります。

実装の確認点

decodeした値をverifyなしで認可へ渡していないか、未署名トークンや入力由来の任意の鍵を許していないか確認します。別用途・期限切れ、アカウント停止や権限変更前のトークンをサーバーがどう扱うか調べます。発行者が署名鍵を更新した後は、受信側が古い検証鍵を受け付ける期間と、古い鍵で署名されたトークンの扱いも確認します。

出典・確認範囲

  1. [1] Web Security Academy: JWT検証の不備PortSwigger / 確認日 2026-11-01
  2. [2] RFC 8725: JSON Web Token Best Current PracticesIETF / 確認日 2026-11-01