September 16, 2021

JSON Web Tokenとは何ですか?

JSON Web Tokenとは何ですか?

JSON WebToken(JWT)は、2.0者間でクレームを転送するURLセーフな方法です。 JWTはクレームをJavaScriptオブジェクト表記でエンコードし、オプションで署名または完全暗号化のためのスペースを提供します。 JWTで提案された標準は、OAuth XNUMXのようなフレームワークや、JWTを活用したOpenID接続のような標準で広く採用されるようになりました。

この記事では、以下について説明します。

JSON Web Tokenとは何ですか?

JSON WebトークンはJSON(JavaScriptオブジェクト表記)であり、いくつかの追加の構造があります。 JWTには、JSON形式を使用するヘッダーとペイロードが含まれています。 オプションで、トークンを暗号化するか、メッセージ認証コード(MAC)で署名することができます。 署名されたトークンは一般にJSONWeb署名(JWS)と呼ばれ、暗号化されたトークンはJSON Web暗号化(JWE)と呼ばれます。

口頭でのコミュニケーションのために、多くの開発者はJWTを「jot」または「jawt」と発音しています。 そのテーマを引き継いで、JWSの発音を「jaws」、JWEの発音を「jawa」として提案します。

世界 JWT ヘッダーJSONとペイロードJSONを「。」で連結することによって形成されます。 オプションで署名を追加します。 文字列全体が base64URLエンコード.

JSONWebトークンの例

JWTの例

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJMTSIsImlhdCI6MTYxOTQ3MDY4MiwiZXhwIjoxNjE5NDcxODg2LCJhdWQiOiJsb2dpY21vbml0b3IuY29tIiwic3ViIjoiTmVkIn0.mqWsk4fUZ5WAPYoY9bJHI7gD8Zwdtg9DUoCll-jXCMg

デコードされたヘッダー

{
  "typ": "JWT",
  "alg": "HS256"
}

デコードされたペイロード

{
  "iss": "LM",
  "iat": 1619470682,
  "exp": 1619471886,
  "aud": "logicmonitor.com",
  "sub": "Ned"
}

署名

mqWsk4fUZ5WAPYoY9bJHI7gD8Zwdtg9DUoCll-jXCMg

JWTを使用する場合

一般的な使用例は、HTTPリクエストの状態をクライアントに残す必要がある場合です。 これは、RESTfulAPI実装の場合によくあります。 RESTful Webサービスは、サーバー上でクライアントの状態を維持することはできませんが、セマンティック的に言えば、ステートレスモデルに厳密に準拠します。 JWTを使用すると、クライアントはリクエストごとにサーバーに状態情報を提供できます。 これは、何らかの形式のクライアント認証と承認制御を必要とする安全なRESTfulWebサービスで特に役立ちます。

セッショントークンで使用できる場合は、JWTを使用しないでください。 一般的に、セッショントークンは、クライアントアクセスを管理するための確立された方法であり、以下に説明する潜在的な脆弱性をもたらすことはありません。 JWTは、ステートレス認証方式が保証されている環境で優れており、シングルサインオン環境が良い例です。 ただし、セッションデータを内部で転送する方法は他にもあり、同等のパフォーマンスでより優れたセキュリティを提供できます。 

JWTは安全ですか?

JSON Web署名(JWS)は、本質的にセキュリティを提供しません。 サービスのセキュリティまたは脆弱性は、実装から発生します。 JWT / JWSの実装によって作成される最も一般的な脆弱性は簡単に回避できますが、必ずしも明白であるとは限りません。 より一般的な脆弱性のいくつかは、JWTヘッダー値がJWTの検証を駆動できるようにする実装から発生します。

JWT処理関数がヘッダーで宣言されたアルゴリズムタイプに盲目的に準拠し、「alg」ヘッダーが「none」に設定されている場合、JWTは、署名が提供する保護なしで有効として処理されます。 これにより、攻撃エージェントはJWT本体のクレーム値を目的に合ったものに設定できます。 処理関数の強化された実装は、ヘッダー値の厳密なセットのみを許可し、それらの制限を満たすJWTのみを検証します。 これは現時点ではよく知られているエクスプロイトであり、最新のJWTライブラリとヘルパー関数のほとんどはこれに対して脆弱ではないはずです。

JWTが署名されている場合でも、注意すべきいくつかの落とし穴があります。 一般的に使用されている署名アルゴリズムには、XNUMXつの基本的なカテゴリがあります。 上記の「なし」アルゴリズム、対称アルゴリズム、および非対称アルゴリズム。 JWT / JWSを消費するサービスによって異なるアルゴリズムの組み合わせが許可されている場合、処理機能は、非同期JWS実装に対して使用される一般的なエクスプロイトから保護する必要があります。

XNUMXつの暗号化アルゴリズム、ハッシュベースのメッセージ認証コード(HMAC)とRivest-Shamir-Adleman(RSA)の例を考えてみましょう。 HMACは、共有秘密鍵を使用して署名を形成および検証します。 非対称アルゴリズムであるRSAは、秘密鍵を使用して署名を形成し、公開鍵を使用して署名を検証します。 RSAアルゴリズムを使用しているシステムは、秘密鍵で署名し、公開鍵で検証します。 JWTがHMACアルゴリズムと入力としての公開RSAキーを使用して署名された場合、受信システムは、HMACアルゴリズムを使用して署名を検証する方法として持っている公開RSAキーを使用しようとすることに騙される可能性があります。 この種の攻撃は、受信システムがJWTヘッダーによるトークン認証の駆動を許可している場合に機能します。 この場合、攻撃者は非対称スキームの公開鍵を対称署名スキームの共有秘密鍵であると宣言しました。 

JWTを実装する際のベストプラクティス

これらの脆弱性を防ぐために、JWTを実装する際にいくつかの基本的なベストプラクティスに従うことができます。

JWTヘッダーがトークンの認証を駆動することを許可しない 

上で概説したように、JWTに認証の制御を与えると、無数の予期しない脆弱性が作成される可能性があります。

弱いトークンシークレットを回避する

弱い秘密は、攻撃者が有効なトークンを生成することを可能にします。

トークンのサイドジャックを防ぐ

トークンにユーザーコンテキストを追加して、トークンを保護します。 ランダムな文字列はクライアント認証中に提供され、たとえば強化されたCookieに保持されます。

安全なトークンストレージを使用する

クライアントトークンが安全な方法で保存されていること、つまり強化されたCookieであることを確認してください。

合理的な有効期限を設定する

強力な署名アルゴリズムを使用する場合でも、トークンが有効である時間を制限することが重要です。 このように、JWTが悪用された場合でも、予測可能な有効期限があります。 トークンを長期間有効にする必要がある場合は、トークンを取り消すためのメソッドを実装することを検討してください。

承認の範囲を制限する

非常に狭い範囲のアクセスでJWTを発行します。 このように、それが悪意のある人の手に渡ったとしても、それは保護されたリソースの削減されたセットへのアクセスのみを提供します。

トークンが提供するアクセスの範囲を制限するクレームを要求する

前のポイントと同様に、受信側でこれらの制限を適用します。 スコープ制限を超えてクレームを行うJWTは、署名の有効性に関係なく拒否する必要があります。

特権データをJWTに保存しない

注意深い観察者は、JWTまたはJWSでさえ、ヘッダーまたはペイロードに格納されているデータを隠そうとしないことに気付くかもしれません。 これは、JWTの使用を検討する際に考慮すべき非常に重要な要素です。 特権情報をJWTに保存しないでください。

サマリー

注意深く検討すれば、JWTの使用は、リソースを管理および保護するための軽量な方法になります。 JWTが解決しようとしている問題に適しているかどうかを評価します。 実装計画を確認し、セキュリティへの影響に特に注意を払ってください。

ネッド・イミング

ネッド・イミング

ソフトウェアエンジニア

Ned Immingは、LogicMonitorの従業員です。