日本語

デコードされた JWT が証明するもの

JWT デコーダーは、トークンが何を主張しているかを示します。それらの主張が真実かどうかを示すことはできません。このガイドでは、3 つのセグメントとは何か、デコードによって確立されるものと確立されないもの、および 2 つのセグメントの間に存在する攻撃について説明します。

3 つのセグメント (そのうち 2 つは単なる JSON)

一般的な形式の JWT は JWS です。つまり、ドットで区切られた 3 つの Base64url セグメントです。 1 つ目はヘッダー、2 つ目はペイロード、3 つ目は署名です。

ヘッダーとペイロードは、base64url エンコードされた通常の JSON オブジェクトです。暗号化ではなくエンコードされます。トークンを持っている人は誰でも、キーなしで両方を瞬時に読み取ることができます。これは欠陥ではなく、設計です。 JWT は署名されたステートメントであり、封をされた封筒ではありません。署名は、ステートメントが変更されていないことを保証します。プライベートを保つためには何もしません。

この結果は日常的に見落とされているため、はっきりと述べる価値があります。JWT ペイロードには機密情報を決して入れないでください。パスワード、完全な国家識別子、内部システムの詳細ではありません。ペイロードはパブリックであると仮定します。トークンを持っている人にとってはパブリックであるためです。

3 番目のセグメントは署名で、最初の 2 つに対して計算されます。これはセキュリティ値を保持する唯一の部分であり、デコーダが評価できない部分です。

解読によって証明されること: 何もない

これがガイド全体のポイントです。 JWT をデコードすると、2 つの Base64url 文字列が JSON に解析されます。これにより、トークンが適切な形式であることが確認されます。トークンが本物であること、"iss" クレームで指定された当事者によって発行されたこと、クレームが編集されていないこと、またはトークンがかつて有効であったことは確認されません。

誰でもトークンを構築できます。任意の JWT を取得し、"role": "user" を "role": "admin" に変更し、ペイロードを再エンコードし、最後に署名をホッチキスで留めると、デコーダーは編集されたクレームを元のクレームと同じように正確に自信を持って表示します。違いのチェックは、デコーダが持っていないキーを必要とする別の操作であるため、違いを知る方法がありません。

したがって、デコーダ (これまたは他のデコーダ) が「exp: 2026-01-01」を表示するとき、それが実際に伝えていることは、このトークンにはその日付で期限切れになるという主張が含まれているということです。その主張が何らかの意味を持つかどうかは、署名が有効かどうか、つまりチェックされていないかどうかに完全に依存します。

このツールはデコードのみを行い、結果の横のページに毎回その旨を表示します。脚注にはありません。その理由は、このことについて黙っているデコーダが、未検証のデータをあたかも検証済みであるかのように読み取るようにユーザーを訓練しており、その習慣が一連の認証バグの根源であるためです。

このツールが検証を提供しない理由

検証には、Web ページが責任を持って保持できない 3 つのものが必要です。それは、発行者のキー、事前に固定されたアルゴリズム、および何を拒否するかに関するポリシーです。

重要なのは明らかな問題です。 HMAC アルゴリズム (HS256 およびその他のアルゴリズム) の場合、キーは共有秘密、つまりトークンの作成に使用されるのと同じ秘密です。これを Web ページに貼り付けるということは、有効なトークンを作成できる資格情報を Web ページに貼り付けることを意味します。 RSA と ECDSA の場合、公開キーは秘密ではありませんが、適切な JWKS エンドポイントから適切な公開キーを取得し、それを信頼する必要があります。

このアルゴリズムは微妙な問題であり、2 つのよく知られた攻撃の原因となっています。 1 つ目は alg: "none" です。ヘッダーはトークンが署名されていないことを主張しており、独自の設定ではなくヘッダーを尊重する検証ツールは何でも受け入れます。 2 つ目は RS256 と HS256 の混同です。攻撃者は公開鍵 (定義上、公開) を取得し、ヘッダーを HS256 に変更し、その公開鍵を HMAC シークレットとして使用してトークンに署名します。トークンからアルゴリズムを読み取り、「キー」を検索する検証者がそれを検証します。

どちらの攻撃も同じ間違いから生じています。つまり、トークンを検証者にトークンのチェック方法を指示させるというものです。正しいベリファイアはヘッダーのアルゴリズムを無視し、設定されているアルゴリズムを使用します。それは、便利なツールやフォームに何かを貼り付けた人ではなく、トークンを信頼するシステムに属する決定です。

なぜ本番トークンをどこにでも貼り付けないのか

アクセス トークンはベアラー資格情報です。これが Authorization ヘッダーの "bearer" の意味です。つまり、それを保持するのはあなたです。 2 番目の要素はなく、通常、盗まれたトークンと正規のトークンを区別する方法はありません。有効期限が切れるまでは、アカウントの有効なキーとして使用されます。

したがって、ライブ トークンを任意の Web ページに貼り付けると、そのページに資格情報が渡されます。これはすべてをローカルでデコードし、ページの読み込み後にネットワーク リクエストを行いません。これはブラウザのネットワーク パネルで確認できますし、確認する必要があります。これには 10 秒かかります。しかし、その議論が実際には何であるかに注目してください。それは、Web サイト上で、その Web サイトが信頼できるという主張です。トークンを盗み出すすべてのサイトはまったく同じ主張をしており、訪問者は一目見ただけでは違いがわかりません。

安全な習慣は、サイトを正しく判断することに依存しません。期限切れのトークン、テスト環境のトークン、または目的のために作成したトークンを使用します。すでに運用トークンをどこか (任意の場所) に貼り付けている場合は、それをローテーションします。取り消しは安価です。事件ではありません。

同じことが、より強力に鍵の署名にも当てはまります。 Web ページに HMAC シークレットまたは秘密キーを入力する正当な理由はありません。トークンを "verify" するために HMAC シークレットまたは秘密キーを要求するサイトは、トークンを偽造する機能を要求していることになります。これが、このツールに検証機能がない具体的な理由です。この機能にはリクエストが必要です。

重要な主張を読む

RFC 7519 は、クレーム名の小さなセットを登録します。 「iss」は発行者、「sub」はトークンの主題、「aud」は対象読者、「exp」は有効期限、「nbf」は最も古い有効時間、「iat」は発行時間、「jti」はリプレイ検出用の一意のIDです。それ以外はすべてアプリケーション固有です。

時間クレームは NumericDate 値、つまりミリ秒ではなく Unix エポックからの秒数です。ほとんどの JavaScript の時間値はミリ秒であるため、これには常につまずく人がいます。 1970 で期限切れになるように見えるトークンには、通常、ミリ秒の値が与えられます。 55000 年に有効期限が切れるように見えるものには、通常、どこかに 1000 を掛けた 2 番目の値が含まれています。

"aud" は、デバッグ時に特に注意が必要です。完全に有効なトークンであっても、異なるユーザー向けに発行されたため、間違ったトークンである可能性があります。署名はチェックするが、オーディエンスはチェックしない検証者は、別のサービス用に作成されたトークンを完全に受け入れます。これは、ID プロバイダーを共有するシステムにおける実際の権限昇格パスです。

このツールは、時刻クレームを UTC で表示し、期限切れのトークンを期限切れとしてマークし、署名が有効な場合にのみ有効期限クレームが意味を持つことを示すリマインダーと組み合わせます。リマインダーが表示されるのは、「有効期限が切れていないと表示される」まさにその瞬間が、未検証のデータの習慣が損害を与える瞬間だからです。

信頼を行うシステムの短いチェックリスト

単にトークンを検査するのではなく、トークンを受け入れるコードを作成している場合、正しい検証ツールが行う動作の短縮版を以下に示します。

  1. クレームを読む前に、まず帯域外で取得したキーを使用して署名を検証してください。
  2. アルゴリズムを独自の構成に固定します。決してトークンヘッダーから読み取らないでください。 "none" を無条件に拒否します。
  3. "exp" と "nbf" を、信頼できるクロックに対して、最大でも小さなスキュー許容値でチェックします。
  4. "iss" と "aud" が予想される値と照合してください。他の人に宛てたトークンの有効な署名は、依然として間違ったトークンです。
  5. 自分で組み立てるのではなく、プラットフォーム用の精査されたライブラリを使用してください。このリストにあるすべての項目は、実装が間違っているために記載されています。
  6. トークンの有効期間を短く保ち、失効パスを用意します。有効期間の短いトークンは、まだ気づいていない漏洩による被害を制限します。

貼り付けたものはどうなりますか

  • すべての変換、ハッシュ、デコード、差分はブラウザーのタブで実行されます。ページが読み込まれるとサーバーは関与しないため、入力はサーバーにアップロード、記録、または保存されません。
  • ハッシュはブラウザー独自の Web Crypto 実装から取得され、UUID は暗号的に安全なランダム ジェネレーターから取得されます。どちらもネットワーク通話を必要としません。
  • 入力した内容はローカル ストレージや Cookie に書き込まれません。ページをリロードするとページは破棄されます。タブを閉じると破棄されます。
  • サイト全体の分析は、構成された正規実稼働ホスト上でのみ実行され、プライバシー ポリシーで開示されます。ローカルホストとプレビューホストはそれを拒否します。貼り付けられた値、トークン、URL、およびファイルの内容は、ToolAcre 独自の分析イベントから除外されます。現在の構成では広告は無効になっています。
  • つまり、JWT または API キーはライブ認証情報です。安全な習慣は、この主張を含め、その主張がどれほど信頼できるものであっても、自分が書いていない Web ページに貼り付けることは決してしないことです。

質問

このツールは署名を検証しますか?

いいえ、決してそんなことはありません。ヘッダーとペイロードをデコードし、その内容が表示されます。署名はチェックされないため、表示されるものは、トークンが本物であること、変更されていないこと、またはトークンの名前が誰によって発行されたものであるかを証明するものではありません。

では、トークンが本物であることはどうやってわかるのでしょうか?

トークンから読み取るのではなく独自の構成に固定されたアルゴリズムを使用して、精査されたライブラリを使用して、発行者のキーで署名を検証します。これは、キーを正当に保持する環境で、トークンを信頼するサービスの作業です。

ここでトークンをデコードすると、どこかにトークンが送信されますか?

いいえ。デコードはページ独自の JavaScript を使用してブラウザー タブで行われ、ページの読み込み後にネットワーク リクエストは行われません。これはブラウザのネットワーク パネルで確認できます。実稼働トークンを習慣として Web ツールに貼り付けないでください。その習慣は、それについて正直ではないサイトでも機能する必要があるからです。

私の JWT ペイロードを誰でも読み取ることができるのはなぜですか?

ペイロードは暗号化されず、base64url でエンコードされているためです。 JWS は署名されたステートメントであり、封印されたステートメントではありません。コンテンツを読み取り不可能にする必要がある場合は、暗号化されたトークン形式である JWE が必要です。その場合、キーがなければデコーダーは何も表示できません。

alg: "none" とは何ですか?

トークンが署名されていないことを宣言するヘッダー値。これは他の手段で整合性が保証されているコンテキストの仕様に存在しており、常駐の罠です。ヘッダーのアルゴリズムを信頼する検証者は、"none" を主張するあらゆるトークンを受け入れます。このツールは、出現するたびにフラグを立てます。

私のトークンには 5 つのセグメントがあり、デコードできません。なぜ?

5 つのセグメントは、署名された JWS ではなく、JWE (暗号化されたトークン) を意味します。復号化キーがなければその内容を読み取ることはできないため、デコーダーが表示できるものはまったくありません。このツールは、あいまいな解析失敗を報告するのではなく、そのケースを明示的に識別します。

有効期限が 1000 倍間違っているように見えます。

JWT 時間クレームは、ミリ秒ではなく、エポックからの秒数である NumericDate: です。 Date.now() によって生成される値は 1,000 倍も大きすぎます。このツールキットのタイムスタンプ ユーティリティは、2 つのタイムスタンプを変換し、使用した単位を常に通知します。

JWT を localStorage に保存しても安全ですか?

それはトレードオフであり、「はい」か「いいえ」ではありません。 localStorage はオリジン上で実行されている任意の JavaScript によって読み取り可能であるため、単一の XSS 脆弱性によってトークンが漏洩されます。 httpOnly Cookie は JavaScript では読み取れませんが、CSRF 保護が必要です。正直な要約は、どちらも無料ではなく、決定はアプリケーションの脅威モデルに属するということです。

制限事項

  • このツールはデコードのみを行います。署名は検証されません。これは欠落している機能ではなく、永続的な設計上の決定です。その理由については、上記のガイドを参照してください。
  • 暗号化されたトークン (JWE、5 つのセグメント) は、キーがなければ復号化できません。ツールはそれらを識別して停止します。
  • ネストされた JWT (ペイロード自体がトークンであるトークン) は、自動的にはラップ解除されません。内部トークンを別のステップとしてデコードします。
  • RFC 7519 で定義されている登録セットを超えるクレームの意味はアプリケーション固有であるため、ツールはそれらの値を解釈せずに表示します。
  • ここに示されている有効期限は、トークンがそれ自体について主張している内容のみを反映しています。その主張が意味があるかどうかは、このツールがチェックしない署名によって異なります。
  • 200,000 文字を超えるトークンは拒否されます。実際の JWT はどれも桁違いに小さいです。