JWTヘッダーのalgフィールド
JWTヘッダーのalg(アルゴリズム)フィールド、サポートされる全アルゴリズム値、「none」アルゴリズムの脆弱性、アルゴリズム許可リストの重要性を解説します。
詳細な説明
alg(アルゴリズム)ヘッダーパラメータは、JWTを保護するために使用される暗号アルゴリズムを識別します。JWTヘッダーで唯一の必須フィールドであり、セキュリティと相互運用性の両方にとって重要です。この値は、サーバーがトークンの署名を検証(または作成)する方法を決定します。
サポートされるアルゴリズム値:
JSON Web Algorithms(JWA)仕様(RFC 7518)は、いくつかのアルゴリズムファミリーを定義しています:
| アルゴリズム | タイプ | 説明 |
|---|---|---|
| HS256, HS384, HS512 | 対称 | SHA-2を使用するHMAC |
| RS256, RS384, RS512 | 非対称 | SHA-2を使用するRSASSA-PKCS1-v1_5 |
| ES256, ES384, ES512 | 非対称 | SHA-2を使用するECDSA |
| PS256, PS384, PS512 | 非対称 | SHA-2を使用するRSASSA-PSS |
| EdDSA | 非対称 | Edwards曲線DSA(Ed25519/Ed448) |
| none | なし | 署名なしJWT(署名なし) |
「none」アルゴリズムの脆弱性:
"none"アルゴリズムは署名なしのJWTを生成します。整合性が他の手段(TLSチャネルなど)で保証されるコンテキスト向けに存在します。しかし、サーバーが受信トークンから"none"アルゴリズムを受け入れる場合、攻撃者は任意のペイロードを作成し、algを"none"に設定するだけで、サーバーは署名検証なしにそれを受け入れます。これは最初に発見された重大なJWT脆弱性の一つであり、多数のライブラリに影響を与えました。
// 攻撃: 攻撃者がこのヘッダーを作成
{ "alg": "none", "typ": "JWT" }
// トークン: eyJhbGciOiJub25lIn0.eyJzdWIiOiJhZG1pbiJ9.
// 署名不要!
アルゴリズム混同攻撃:
もう一つの攻撃は、アルゴリズムの切り替えです。サーバーがRS256(非対称)用に設定されている場合、攻撃者はヘッダーをHS256(対称)に変更し、サーバーの公開鍵(公開されている)でトークンに署名する可能性があります。サーバーがトークンのalgヘッダーを使用して検証方法を選択する場合、公開鍵を秘密鍵としてHMACを検証し、偽造トークンが検証を通過します。
必須の防御策: アルゴリズム許可リスト:
JWTライブラリには受け入れるアルゴリズムの明示的なリストを常に設定してください。トークン自体がサーバーの検証に使用するアルゴリズムを指定することを決して許可しないでください。この一つのプラクティスで、"none"アルゴリズム攻撃とアルゴリズム混同攻撃の両方を防ぎます。
// 許可するアルゴリズムを常に指定
jwt.verify(token, key, { algorithms: ['RS256'] });
ユースケース
セキュリティエンジニアがAPIゲートウェイをRS256トークンのみ受け入れるように設定し、攻撃者がヘッダーをHS256やnoneに切り替えるアルゴリズム混同攻撃を防ぎます。