| RFC 8725 | JWT BCP | 2020年2月 |
| Sheffer, et al. | ベストカレントプラクティス | [Page] |
JSON Web トークン(JWTとしても知られる)は、URLセーフなJSONベースのセキュリティ トークンで、署名および/または暗号化可能な一連のクレームを含みます。 JWTは広く使用され、数多くのプロトコルやアプリケーションで、デジタルアイデンティティ分野だけでなく 他のアプリケーション領域でも、シンプルなセキュリティトークン形式として展開されています。 本ベストカレントプラクティス文書はRFC 7519を更新し、JWTの安全な実装と展開に つながる実践的な指針を提供します。¶
このメモはインターネットのベストカレントプラクティスを文書化したものです。¶
本文書はInternet Engineering Task Force (IETF)の成果物です。IETFコミュニティのコンセンサスを反映しています。 公開レビューを経て、Internet Engineering Steering Group (IESG) により出版が承認されています。 BCPに関する詳細はRFC 7841の第2節に記載されています。¶
本文書の現状、訂正情報、およびフィードバックの提供方法については https://www.rfc-editor.org/info/rfc8725で確認できます。¶
Copyright (c) 2020 IETF Trust and the persons identified as the document authors. All rights reserved.¶
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Simplified BSD License.¶
JSON Web Token(JWT)はURLセーフなJSONベースのセキュリティトークンで、 署名や暗号化が可能なクレーム群を含むことができます。 JWT仕様は、セキュリティ関連情報を1箇所にまとめて保護できる点と、 幅広く利用可能なツールで簡単に実装できる点から急速に普及しました。 JWTがよく使われる応用分野の1つはデジタルID情報の表現であり、 OpenID ConnectのIDトークンやOAuth 2.0のアクセストークン・リフレッシュトークンなどが含まれます。 詳細は導入環境によって異なります。¶
JWT仕様が公開されて以来、実装や運用上の攻撃がいくつか報告されています。 これらは、セキュリティ機構が十分に規定されていなかったこと、 実装が不完全であったこと、またアプリケーションによる誤用が原因です。¶
本文書の目的は、JWTの安全な実装および運用を促進することです。 多くの推奨事項は、JSON Web Signature(JWS)、 JSON Web Encryption(JWE)、およびJSON Web Algorithms(JWA)で定義される 暗号化機構の実装・使用に関するものです。 その他はJWTのクレームの使用に関する推奨事項です。¶
これらは、ほとんどの実装・運用シナリオにおけるJWT使用の最小限の推奨事項です。 本文書を参照する他の仕様では、特定の状況に応じてより厳しい要件を定める場合があります。 その場合、実装者はより厳しい要件に従うことが推奨されます。 なお、本書は最低限の基準を示すものであり、より強力な選択肢を採用することも可能です。¶
アルゴリズムの強度や攻撃の現実性に関する知識は迅速に変化します。 セキュリティに関するBCP(Best Current Practice)は時点に依存するため、 読者は本書の修正や更新情報を確認することが推奨されます。¶
本文書で使用されるキーワード "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", "OPTIONAL" は、 BCP 14 に従って解釈されます。 ただし、すべて大文字で書かれた場合に限ります。¶
このセクションでは、JWTの実装および展開における既知および潜在的な問題のいくつかを示す。 各問題の説明の後には、その問題に対する1つ以上の軽減策への参照が続く。¶
署名されたJSON Web Tokenは、暗号アルゴリズムの変更性を容易にするために、 "alg" ヘッダパラメータの形で署名アルゴリズムを明示的に示す。 これに加え、一部のライブラリやアプリケーションの設計上の欠陥により、いくつかの攻撃が発生している。¶
さらに、一部のアプリケーションは "HS256" のような鍵付きメッセージ認証コード(MAC)アルゴリズムを使用してトークンに署名するが、 エントロピーが不十分な弱い対称鍵(人間が覚えやすいパスワードなど)を使用している場合がある。 このような鍵は、攻撃者がトークンを入手した場合、オフラインの総当たり攻撃や辞書攻撃に対して脆弱である。[Langkemper]。¶
JWEで暗号化されたJWTを復号してJWS署名されたオブジェクトを取得する一部のライブラリは、 内部署名を常に検証するわけではない。¶
多くの暗号アルゴリズムは、平文の長さに関する情報を漏洩する。漏洩量はアルゴリズムや運用モードに依存する。 平文が最初に圧縮されている場合、この問題は悪化する。なぜなら、圧縮後の平文の長さ、ひいては暗号文の長さは元の平文の長さだけでなく、内容にも依存するからである。 圧縮攻撃は、攻撃者が制御できるデータが秘密データと同じ圧縮空間にある場合に特に強力であり、これはHTTPSに対する一部の攻撃で見られる。¶
圧縮と暗号化の一般的な背景については [Kelsey] を、 HTTPクッキーに対する攻撃の具体例については [Alawatugoda] を参照。¶
[Sanso] によると、いくつかのJavaScript Object Signing and Encryption (JOSE) ライブラリは、 楕円曲線鍵共有("ECDH-ES"アルゴリズム)を実行する際に入力を正しく検証できない。 攻撃者が無効な曲線点を使用した任意のJWEを送信し、その無効な曲線点で復号した平文を観察できる場合、この脆弱性を利用して受信者の秘密鍵を回復することができる。¶
以前のJSONフォーマット(廃止された [RFC7159] など)は、UTF-8、UTF-16、UTF-32など複数の文字エンコーディングを許可していた。 現在の標準 [RFC8259] では、内部的な「閉じたエコシステム」内での使用を除き、UTF-8のみを許可している。 この曖昧さにより、古い実装や閉じた環境で使用される実装が非標準のエンコーディングを生成する可能性があり、JWTが受信者によって誤解される可能性がある。 これにより、悪意のある送信者が受信者の検証チェックを回避することができる。¶
受信者が本来意図されたJWTを別の受信者で使用しようとする攻撃が存在する。 例えば、OAuth 2.0 [RFC6749] アクセストークンが正当に 意図されたOAuth 2.0保護リソースに提示された場合、その保護リソースが同じアクセストークンを 意図されていない別の保護リソースに提示し、アクセスを試みる可能性がある。 このような状況を検出できない場合、攻撃者が本来アクセス権のないリソースにアクセスできる可能性がある。¶
JWTが異なるプロトコルや多様なアプリケーション領域で使用されるにつれ、 ある目的で発行されたJWTが他の目的で悪用されることを防ぐことがますます重要になる。 これは特定の置換攻撃の一種であることに注意。 JWTが他の種類のJWTと混同されうるアプリケーションコンテキストで使用される場合、 このような置換攻撃を防ぐために軽減策 MUST が必要である。¶
さまざまなJWTクレームは、受信者がデータベースやLDAP検索などのルックアップ操作を行うために使用される。 他には、同様にサーバーがルックアップするURLなどがある。 これらのクレームはいずれも、攻撃者によって注入攻撃やサーバーサイドリクエストフォージェリ(SSRF)攻撃のベクターとして利用される可能性がある。¶
以下に列挙するベストプラクティスは、前節で示した脅威を軽減するために実務者が適用すべきものです。¶
ライブラリは呼び出し元がサポートされるアルゴリズムの集合を指定できるようにしMUST、暗号操作を行う際にそれ以外のアルゴリズムを使用してはならないMUST NOT。 ライブラリは "alg" または "enc" ヘッダが暗号操作で使用されるのと同じアルゴリズムを指定していることをMUST 確保する必要がある。 さらに、各キーは厳密に一つのアルゴリズムでのみ使用されるべきであり、そのことは暗号操作が実行される際に確認されなければならないMUST。¶
[セクション5.2 of [RFC7515]が述べるように、 「特定の文脈でどのアルゴリズムが使用できるかはアプリケーションの判断である。たとえ JWS が正常に検証できたとしても、JWS で使用されたアルゴリズムがアプリケーションにとって受け入れられるものでない限り、アプリケーションは当該 JWS を無効とみなすべきである」とある。¶
したがって、アプリケーションは暗号的に現在安全とされるアルゴリズムのみを許可しMUST、アプリケーションのセキュリティ要件を満たす必要がある。 この集合は新しいアルゴリズムの導入や既存アルゴリズムが暗号的弱点により非推奨になるに従って時間とともに変化する。 よってアプリケーションは暗号のアジリティを可能にするよう設計されなければならないMUST。¶
とはいえ、JWT が TLS のような輸送層でエンドツーエンドに暗号的に保護されており、かつその輸送が暗号的に現在安全なアルゴリズムを使用している場合、JWT に別の暗号保護層を適用する必要はないかもしれない。 そのような場合、"none" アルゴリズムの使用は完全に容認され得る。 "none" アルゴリズムは JWT が他の手段によって暗号的に保護されている場合にのみ使用されるべきである。 "none" を使用する JWT は、署名が任意であるアプリケーション文脈で用いられることが多く、その場合、URL 安全なクレーム表現と処理は署名あり・なしの両方で同一にできる。 JWT ライブラリは明示的に呼び出し元に要求されない限り "none" を使用して JWT を生成すべきでないSHOULD NOT。 同様に、JWT ライブラリは明示的に呼び出し元に要求されない限り "none" を使用する JWT を消費すべきでないSHOULD NOT。¶
アプリケーションは次のアルゴリズム固有の推奨事項に従うべきであるSHOULD:¶
JWT で使用されるすべての暗号操作は検証されるべきであり、いずれかが検証に失敗した場合は JWT 全体を拒否しなければならないMUST。 これはヘッダパラメータが単一のセットである JWT に限らず、外側と内側の両方の操作が検証されるべきネストされた JWT に対しても同様であり、これらはアプリケーションによって提供されるキーとアルゴリズムを用いて検証されなければならないMUST。¶
楕円曲線ディフィー・ヘルマン鍵共有("ECDH-ES")のような一部の暗号操作は、指定された楕円曲線上にない点やその他の無効な点(例: [Valenta]、セクション7.1)を含む無効な値を入力として取る可能性がある。 JWS/JWE ライブラリ自体がこれらの入力を使用する前に検証するか、あるいは基盤となる暗号ライブラリがそれを行う(またはその両方)必要がある。¶
楕円曲線ディフィー・ヘルマン Ephemeral-Static(ECDH-ES)のエフェメラル公開鍵(epk)入力は、受信者が選択した楕円曲線に従って検証されるべきである。NIST の素数位数曲線 P-256、P-384、P-521 の場合、検証は"Recommendation for Pair-Wise Key-Establishment Schemes Using Discrete Logarithm Cryptography" のセクション5.6.2.3.4(ECC 部分公開鍵検証ルーチン)に従って行われるべきである[nist-sp-800-56a-r3]。 "X25519" または "X448" のアルゴリズムが使用される場合は、[RFC8037] に記載されたセキュリティ考慮事項が適用される。¶
キーのエントロピーとランダム値に関する助言は、[RFC7515 セクション10.1]および[RFC7518 セクション8.8]のパスワードに関する考慮事項に従うべきであり、これらは守られなければならないMUST。特に、人間が記憶可能なパスワードを "HS256" のような keyed-MAC アルゴリズムのキーとして直接使用してはならないMUST NOT。 さらに、パスワードはコンテンツ暗号化よりも鍵暗号化を行うためにのみ使用されるべきであり、その詳細は [RFC7518 セクション4.8] に記載されている。鍵暗号化に用いる場合でも、パスワードベースの暗号化は総当たり攻撃の対象となる点に注意する必要がある。¶
データの圧縮は暗号化の前に行うべきではないSHOULD NOT。圧縮されたデータはしばしば平文に関する情報を明らかにするためである。¶
[RFC7515]、[RFC7516]、および [RFC7519] はすべて、ヘッダパラメータおよび JWT クレームセットで使用される JSON のエンコードおよびデコードに UTF-8 を使用することを指定している。これは最新の JSON 仕様書 [RFC8259] とも一致する。 実装およびアプリケーションはこれを行い、これらの目的のために他の Unicode エンコーディングを使用したり許容したりしてはならないMUST。¶
JWT に "iss"(発行者)クレームが含まれる場合、アプリケーションは JWT の暗号操作に使用された暗号鍵が発行者に属することを検証しなければならないMUST。 もし属していない場合、アプリケーションは JWT を拒否しなければならないMUST。¶
発行者が所有する鍵を特定する手段はアプリケーション固有である。一例として、OpenID Connect [OpenID.Core] の発行者値は JSON メタデータ文書を参照する "https" URL であり、その文書には発行者の鍵が JWK セットとして取得される "jwks_uri" 値("https" URL)を含む。このメカニズムは [RFC8414] でも使用される。その他のアプリケーションは異なる手段で鍵と発行者を結び付ける場合がある。¶
同様に、JWT に "sub"(主体)クレームが含まれる場合、アプリケーションは主体値が有効な主体および/またはアプリケーションにおける発行者-主体の組と対応していることを検証しなければならないMUST。 これには発行者がアプリケーションによって信頼されていることの確認を含む場合がある。もし発行者、主体、またはその組が無効であれば、アプリケーションは JWT を拒否しなければならないMUST。¶
同じ発行者が複数の依存当事者またはアプリケーション向けに JWT を発行できる場合、JWT は "aud"(オーディエンス)クレームを含み、その値を使用して JWT が意図された当事者によって使用されているか、攻撃者によって意図しない当事者に差し替えられていないかを判断できるようにしなければならないMUST。¶
そのような場合、依存当事者やアプリケーションはオーディエンス値を検証しなければならないMUST。 もしオーディエンス値が存在しないか受信者に関連付けられていない場合、JWT を拒否しなければならないMUST。¶
"kid"(キーID)ヘッダは依存アプリケーションが鍵検索を行うために使用される。アプリケーションはこれが SQL や LDAP インジェクションの脆弱性を生じさせないよう、受け取った値を検証および/またはサニタイズすることを保証すべきである。¶
同様に、任意の URL を含み得る "jku"(JWK セット URL)や "x5u"(X.509 URL)ヘッダを盲目的にたどることは、サーバーサイドリクエストフォージェリ(SSRF)攻撃を招く可能性がある。アプリケーションはそのような攻撃に対して保護すべきでありSHOULD、例えば URL を許可された場所のホワイトリストに照合し、GET リクエストでクッキーが送信されないことを確保する等の対策を講じるべきである。¶
場合によっては、ある種類の JWT が別の種類と混同されることがある。もし特定の種類の JWT がそのような混乱の対象となるなら、その JWT は明示的な JWT 型値を含めることができ、検証ルールは型のチェックを指定することができる。このメカニズムはそのような混同を防ぐことができる。 明示的な JWT 型指定は "typ" ヘッダパラメータを使用して行われる。例えば、[RFC8417] 仕様は Security Event Tokens (SET) の明示的な型指定を行うために "application/secevent+jwt" メディアタイプを使用する。¶
[RFC7515 セクション4.1.9] における "typ" の定義によれば、"typ" 値から "application/" プレフィックスを省略することが推奨されるRECOMMENDED。 したがって、例えば SET の型を明示的に含めるために使用される "typ" 値は "secevent+jwt" であるべきだSHOULD。 JWT に明示的な型指定が用いられる場合、"application/example+jwt" の形式のメディアタイプ名を使用することが推奨されるRECOMMENDED。ここで "example" は特定の JWT 種類の識別子に置き換えられる。¶
ネストされた JWT に明示的な型指定を適用する場合、明示的な型値を含む "typ" ヘッダパラメータはネストされた JWT の内側の JWT(ペイロードが JWT クレームセットである JWT)に存在しなければならないMUST。 場合によっては、全体のネストされた JWT を明示的に型指定するために外側の JWT にも同じ "typ" ヘッダパラメータ値が存在することがある。¶
明示的な型指定を用いても既存の種類の JWT からの曖昧性を完全に解消できないことがある点に注意せよ。既存の種類の JWT に対する検証ルールはしばしば "typ" ヘッダパラメータ値を使用していないからである。 新しい JWT の用途に対しては明示的な型指定が推奨されるRECOMMENDED。¶
各 JWT の適用は、必要および任意の JWT クレームとそれらに関連する検証ルールを指定するプロファイルを定義する。 同一の発行者が複数種類の JWT を発行できる場合、それらの JWT に対する検証ルールは相互に排他的になるように記述されなければならずMUST、間違った種類の JWT を拒否すること。 JWT をある文脈から別の文脈へ差し替えられることを防ぐために、アプリケーション開発者は複数の戦略を用いることができる:¶
JWT の用途とアプリケーションの多様性を考えると、異なる種類の JWT を区別するための型、必要なクレーム、値、ヘッダパラメータ、鍵の使用、発行者の最良の組み合わせは、一般にアプリケーション固有である。 新しい JWT アプリケーションに関しては、セクション3.11で述べたように、明示的な型指定の使用が推奨されるRECOMMENDED。¶
この文書全体は、JSON Web Token を実装および展開する際の セキュリティに関する考慮事項について述べています。¶
この文書には IANA に対するアクションはありません。¶
JWE および JWT の実装者に対して "ECDH-ES" の無効点攻撃を注意喚起してくれた Antonio Sanso に感謝します。Tim McLean は RSA/HMAC 混同攻撃を公開しました [McLean]。 明示的な型指定の使用を提唱してくれた Nat Sakimura に感謝します。多くのコメントをくれた Neil Madden に感謝します。またレビューをしてくれた Carsten Bormann, Brian Campbell, Brian Carpenter, Alissa Cooper, Roman Danyliw, Ben Kaduk, Mirja Kühlewind, Barry Leiba, Eric Rescorla, Adam Roach, Martin Vigoureux, and Éric Vyncke に感謝します。¶