最新のアクセス制御は、JSON ベースのトークンの上で生き、そして死んでいく。OAuthのアクセストークン、OpenID ConnectのIDトークン、署名されたAPIセッションを検査するとき、通常は JSONウェブ署名(JWS) 構造に変換する。検索エンジンは、魔法のように不透明な文字列を読みやすいJSONに変えるように見える「jsonウェブ署名デコード」ツールに多くの人々を送る。
攻撃と防御のセキュリティ・エンジニアにとって、これは最初のステップに過ぎない。JWSを解読することで、トークン クレームしかし、その主張が信頼に足るものかどうか、署名が正しく実施されているかどうか、その実装がすでにCVEデータベースに登録されているかどうかなどはわからない。
この記事では、jsonウェブシグネチャのデコードを実行すると実際に何が起こるのか、JWSの検証に関する微妙なミスから現実世界の脆弱性がどのように生まれたのか、そして自動化されたAIによるペンテストパイプラインに適合する再現可能なワークフローを構築する方法について説明する。

JSONウェブ署名の正体
JWS仕様によると、JSON Web Signatureは、JSONベースの構造を使用して、デジタル署名またはMACのいずれかによって保護された任意のコンテンツを表す。JSONウェブ署名は、バイト列の完全性と真正性を提供するものであり、バイト列が何を表しているかに依存しない。(IETFデータトラッカー)
実際には、ほとんどの場合、このバイト列は、JSONオブジェクトの クレーム - これはJSON Web Token (JWT)と呼ばれるものである。JWS自体は[RFC 7515]で定義されているが、JWTはこれらのクレームがどのように構造化され解釈されるかに焦点を当てた兄弟標準にある。(ミディアム)
おなじみのコンパクトな形はこうだ:
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0Iiwic2NvcGUiOlsicmVhZCIsIndyaXRlIl0sImV4cCI6MTczNDkxMjAwMH0.
ODU5Y...signature-bytes-here...
概念的には、Base64URLエンコードされた3つの部分がドットで結ばれている:
| パート | 名称 | 説明 |
|---|---|---|
| 第1チャンク | ヘッダー | アルゴリズム、キーヒント(キッド, jwk, x5u)、トークン・タイプ |
| 第2チャンク | ペイロード | クレーム:件名、スコープ、発行者、有効期限など。 |
| 第3チャンク | 署名 | 署名の出力 base64url(header) + ".".+ base64url(ペイロード) |
jsonウェブ署名のデコード操作は、オンラインツールで実行されるか、独自のスクリプトで実行されるかにかかわらず、最初の2つの部分のBase64URLエンコーディングを反転し、JSONをきれいに印刷するだけです。それは次のようになります。 ない ツールが明示的に既知のキーと制約のあるアルゴリズムセットで検証を行わない限り、署名が有効であることを証明する。(開発者.pingidentity.com)
jsonウェブ署名デコードツールの実際の仕組み
ほとんどのJWT / JWSデコーダー(ブラウザやウェブベースのプレイグラウンドで使われる一般的な開発者ツールなど)は、同じ最小限のパイプラインを実装している:
- 点を3分割する。
- 最初の2つのセグメントをBase64URLデコードする。
- ヘッダーとペイロードをJSONとして解析する。
- 検証キーが提供された場合、ヘッダーで告知されたアルゴリズムを用いて署名を再 計算し、3番目のセグメントと比較する。(開発者.pingidentity.com)
セキュリティ・エンジニアの観点からは、ステップ1~3はオフラインで分析するには十分安全です。
最小限のPythonデコード・スニペット
ペンテスト中にキャプチャしたトークンを grep しているときに便利な、Python による意図的にシンプルなデコードのみのスニペットです:
インポート base64
インポート json
def b64url_decode(data: str) -> bytes:
# JWTのパディング処理
padding = '=' * (-len(data) % 4)
return base64.urlsafe_b64decode(data + padding)
def decode_jws(token: str):
header_b64, payload_b64, signature_b64 = token.split('.')
header = json.loads(b64url_decode(header_b64))
ペイロード = json.loads(b64url_decode(ペイロード_b64))
return header, payload, signature_b64
jws = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...."
h, p, sig = decode_jws(jws)
print("Header:", h)
print("ペイロード:", p)
この関数は 決して はベリファイ・ルーチンを呼び出す。これは、新しいターゲットをトリアージする際に、しばしば正確に望むことである。つまり、暗号的な仮定を全く必要としない高速な検査である。
検証付きNode.jsスニペット
デコードから検証に移れば、細部が重要になる:
jsonwebtoken" から jwt をインポートする;
import fs from "fs";
const publicKey = fs.readFileSync("public.pem", "utf-8");
関数 verifyJws(token) {
// 重要:サポートされているアルゴリズムを明示的にロックダウンする。
return jwt.verify(token, publicKey, {)
algorithms: ["RS256"]、
});
}
を省略した場合 アルゴリズム ホワイトリストに登録し、信頼されていないヘッダーからアルゴリズムをライブラリに推測させることは、複数のJWT CVEにつながった条件をまさに再現することになる。
デコードは無害であり、デコードされたデータは信頼されない。
インシデント・レポートやCVEを見ると、開発者は次のようなパターンを繰り返している。 デコード済み JWT / JWSのデータは、あたかもすでに存在しているかのようだ。 検証済み.JWTのセキュリティ問題についての複数の最新の記述は、Base64URLのデコードは些細なことであり、トークンの秘密性は "読みにくいこと "から来るものではないことを強調している。(ポートスウィガー)
繰り返し発生する3つのバグが目立つ:
- alg "フィールドは真実のソースとして扱われる。 検証コードがヘッダーから使用するアルゴリズム(これはユーザーが制御できる)を引き出すと、アルゴリズム混乱攻撃を招くことになる。
- について
なしアルゴリズムが誤って受け入れられた。 JWT標準は、歴史的に以下のサポートを必要としていた。"なし"を "完全性保護なし "を意味するアルゴ リズムとして使用する。Auth0の古典的な分析では、いくつかのライブラリがこの選択をいかに素朴に尊重し、署名されていないトークンがチェックをパスすることを許可しているかが示された。(認証0) - 重要なヒント
キッド埋め込みjwk,x5u)は検証されない。 JWS RFCもテストガイドも、厳密なホワイトリストなしでトークンが独自の検証鍵を選択できるようにすると、攻撃者が任意の公開鍵を密輸したり、攻撃者が管理する場所で鍵検索を強要したりできることを強調している。(ポートスウィガー)
言い換えれば、jsonウェブ署名デコードは観測可能性を与える。信頼は得られない。この違いが、安全なデバッグのセットアップとリモート・コード実行のヘッドラインを分けるのだ。
デコードとCVEが出会うとき:具体的なJWSの失敗モード
デコードとベリファイが混同されると、どれだけ悪いことが起こるかを理解するために、JWSの検証ロジックにまつわるいくつかのCVEを見る価値がある。
CVE-2015-9235 - HS/RS におけるキーの混乱 jsonwebtoken
Node.jsでは jsonwebtoken バージョン4.2.2以前のモジュールでは、設計ミスにより、非対称アルゴリズム(RS256 / ES256ファミリー)から対称アルゴリズム(HS256)に切り替えることで、署名検証をバイパスすることが可能でした。脆弱なコード・パスは、攻撃者がHMACの秘密鍵を変更した際に、同じ値(RSA公開鍵)をHMACの秘密鍵として再利用していた。 アルグ ヘッダを HS256 に送る。(nvd.nist.gov)
攻撃者の視点から見れば、作業の流れは単純だ:
- オリジナルのトークンをデコードし、ヘッダーを検査する。
- サーバーの公開鍵を取り出す(例えば、JWKエンドポイントや証明書から)。
- 公開鍵をHMACシークレットとして使い、HS256ヘッダーで新しいトークンを偽造する。
- 偽造トークンを提示すると、サーバーはそれを有効なものとして誤って扱う。
ここでは、デコードが攻撃者に素材(ヘッダー、アルゴリズム、キーの位置)を与え、検証ロジックが残りを行った。
CVE-2018-1000531 - を受け入れます。 なし アルゴリズム
この脆弱性は、ライブラリが なし アルゴリズムは、署名がないにもかかわらず、効果的にそれらを有効なものとして扱う。悪用パターンはほとんど滑稽なほど単純である。 "alg":"RS256" への "alg":"なし"署名部分を削除し、ターゲットAPIがそのトークンを受け入れるかどうかを確認する。(0xn3va.gitbook.io)
CVE-2023-48238 - アルゴリズムの混乱 json-web-token
について json-web-token JavaScript用のライブラリが、別のアルゴリズム混同攻撃に対して脆弱であることが判明した。核心的な問題は、検証に使われるアルゴリズムがトークン・ヘッダから直接取られていたことである。そのため攻撃者は、サーバー運営者が強制していると思っているアルゴリズムよりも便利なアルゴリズムを選ぶことができた。(nvd.nist.gov)
CVE-2024-54150 - C による JWT 実装の混乱
最近では cjwt Cライブラリには、現在CVE-2024-54150として追跡されている重大なアルゴリズム混同の欠陥があった。コード・レビューの結果、トークンを検証する際に、HMACベースのアルゴリズムとRSA / ECのアルゴリズムを適切に区別して実装していないことが判明した。(nvd.nist.gov)
これらのケースは歴史的な珍事ではなく、2023年から2024年にかけても、JWSの検証パスにおける微妙なミスが、深刻な脆弱性の活発な原因であることを示している。
アセスメント中、それらを整理しておくために、多くのチームは次のようなカンニングペーパーを作成する:
| CVE | 根本原因 | 攻撃テーマ | メインレッスン |
|---|---|---|---|
| 2015-9235 | HSとRSのキー混乱 | アルゴリズムの混乱 | アルゴリズムごとにキーを分ける。 |
| 2018-1000531 | なし 署名として認められる | ヌル・シグネチャー | 決して許さない なし 生産中 |
| 2023-48238 | 信頼できないJWTからのアルゴリズム | アルゴリズムの混乱 | ヘッダーを無視する アルグサーバー側の設定のみを使用 |
| 2024-54150 | HSとRS/ECの区別なし | アルゴリズム混乱(C) | MACとシグネチャーを根本的に異なる経路として扱う |
jsonウェブ署名をデコードする練習の際、観測されたトークンをこのテーブルに明示的にマッピングすることで、どのプレイブックを試すべきかを素早く見つけることができる。
ペンテスターのための実用的なデコード・ファーストのワークフロー
JWSに依存するAPIやSSOシステムを評価する場合、規律正しいデコード・ファーストのワークフローは、盲点やノイズの多い推測を避けることができる。
- トークンを捕獲し、カタログ化する。 プロキシまたはテストハーネスを使用して、すべてのトークンをキャプチャする:認証ヘッダ、クッキー、URL パラメータ。発行者と利用者によってグループ化する。
- ヘッダーとペイロードをオフラインでデコードする。 上のPythonのスニペットのようなスクリプトを使うか、あるいは
jwt_tool実戦では、機密性の高いトークンをオンライン・サービスに頼ってはならない。(ギットハブ) - ヘッダーマトリクスを構築する。 各トークンファミリーについて
アルグ,キッドが存在する。ジュク/jwk/x5uそしてあらゆるカスタムヘッダーフィールド。これは、PortSwiggerの組み込みJWKと攻撃者が提供するキーに関するガイダンスが、直接実行可能になる場所である。(ポートスウィガー) - 鍵の管理パターンを推測する。 ヘッダーフィールドとよく知られたエンドポイント(
/.well-known/jwks.json)、キーがどのように分配され、回転されるかをスケッチする。 - 既知のクラスのバグをテストする。
- ヌルシグネチャーを試す
なしそのライブラリやスタックが歴史的にサポートしていた場合、その変種を使うことができる。 - アルグがロックダウンされていない場所でHS/RSキーの混同を試みる。
- プローブ
キッドディレクトリトラバーサルやファイルインクルード動作のハンドリング。 - JWKインジェクションの埋め込みを試みる。
- ヌルシグネチャーを試す
- それから、そしてそのとき初めて、完全な搾取の試みに移る。 この段階では、ただブラックボックスにペイロードを投げるのではなく、何を証明しようとしているのかを正確に知るべきである。
このプロセスにおいて、jsonウェブ署名のデコードは、残りの攻撃手法のための観測可能なレイヤーとなる。

AI主導のペンテスト・パイプラインにjsonウェブ署名デコードを統合する (ペンリジェント)
手作業による分析は、単一のエンゲージメントには有効だが、規模が大きくなると、チームにはパイプラインに近いものが必要になる。AI支援プラットフォーム ペンリジェント は、jsonウェブシグネチャのデコードを偵察と攻撃のフェーズに直接組み込むことができる。
典型的なセットアップでは、プラットフォームはブラウザのサンドボックスやプロキシからHTTPトラフィックを取り込み、自動的にトークンの候補を抽出し、ヘッダーとペイロードに対してJWSの一括デコードを実行する。AIエージェントは次に、トークンを発行者、アルゴリズム、キーヒントごとにクラスタリングし、予期しないアルゴリズムの多様性、奇妙なトークン、不正なトークンなどの異常を探します。 キッド エンコーディングや珍しいクレームの組み合わせ。
このベースラインが構築されると、Penligentの攻撃エンジンは自動的にJWT/JWSプレイブックをキュレートして実行することができます。 ジュク 悪用、および既知のCVEにインスパイアされたプローブ。これらのチェックを人間の記憶に委ねるのではなく、システムはすべてのターゲットで実行される反復可能なテストケースとして扱い、結果を証拠優先のリスクリストと機械可読レポートにフィードバックする。
社内の「AIレッド・チーム」機能を構築するセキュリティ・エンジニアにとって、jsonウェブ・シグネチャ・デコードをこのような自動パイプラインに配線することは、低レベルの配管の中で最も活用度が高いものの1つであることが多い。
ハードニングのチェックリストと参考文献
もしあなたの本業がJWS / JWTトークンの発行や検証に関わるのであれば、これを最低限の基準として扱うことができる:
- サーバー側で許可されたアルゴリズムの厳格なリストを強制する。
アルグ信頼されていないトークンからポリシーとして - 非対称署名とHMAC秘密鍵は別々にする。RSA公開鍵をHMAC鍵として再利用しないこと。
- 永久に無効にする
なしプロダクション・ライブラリーでは、それを宣伝するトークンを拒否する。 - すべてのヘッダーフィールド (
キッド,ジュク,jwk,x5u)を信頼できない入力とみなし、固定された鍵セットまたはホワイトリストと照合して検証する。 - JWTライブラリにパッチを適用しておいてください。CVE-2015-9235、CVE-2018-1000531、CVE-2023-48238、CVE-2024-54150などのCVEを定期的に確認し、スタックが影響を受けていないかどうかを確認してください。(スイススキー研究室)
- リグレッション・テストを追加して、明示的に「なし/アルゴリズム混乱」のシナリオを実行する。
より深く掘り下げるには、これらの英語の参考文献をブックマークし、社内のランブックからリンクする価値がある:
- IETFのコア[JSON Web Signature (JWS) RFC 7515]。(IETFデータトラッカー)
- OWASP のウェブ・セキュリティ・テスト・ガイドの[JSON ウェブ・トークンのテスト]のセクション。(OWASP財団)
- PortSwiggerのWebセキュリティ・アカデミーのラボで、[JWT攻撃]と[アルゴリズムの混乱]について。(ポートスウィガー)
- Tim McLean氏の古典的なAuth0の記事[JSON Web Tokenライブラリにおける重大な脆弱性]。(認証0)
- IETF OAuthワーキンググループで進行中の[JWT Best Current Practices]ドラフト。(インターネット技術特別調査委員会)
正しく使用されれば、jsonウェブ署名デコードは単なるデバッグの利便性ではなく、アプリケーションの認証基盤を理解し、攻撃し、強化する体系的な方法へのフロントドアとなる。

