エラーメッセージ
"alg" (Algorithm) Header Parameter value not allowed
jose (JavaScript) — JOSEAlgNotAllowed, code ERR_JOSE_ALG_NOT_ALLOWED
このエラーの意味
トークンの alg ヘッダーで指定されたアルゴリズムが、jwtVerify に渡したアルゴリズムの許可リストに含まれていません。jose は暗号処理を始める前の段階で拒否します。このチェックは意図的なものです。alg ヘッダーは攻撃者が制御できる入力であり、アルゴリズムはトークンではなく検証者が選ばなければなりません。
発生する理由
許可リストが発行者の設定とずれている
よくある発行者が RS256 から ES256 に移行した(または別のアルゴリズムの新しい署名鍵を追加した)のに、検証者がまだ古いアルゴリズムファミリーに固定されたままです。許可リストと鍵を一緒に更新するまで、新しいトークンはすべて失敗します。また、失敗の開始時刻は発行者が変更を展開した時刻と分単位で一致するため、ログを調査するうえで有用な手がかりになります。
許可リストでのアルゴリズム名の表記が異なる
ときどき比較は JOSE の名前との完全一致で、大文字と小文字も区別されます。設定ファイルに「es256」「ECDSA」「P-256」「SHA256withECDSA」と書いても、「ES256」と記載されたヘッダーとは決して一致しません。(ES256 トークンに P-384 の鍵を使う場合や、JWK 自体の alg が異なる場合など、ヘッダーに合わない鍵は別の形で失敗し、鍵の問題を説明する TypeError が発生します。)
悪意のあるクライアントや設定を誤ったクライアントが alg を変えてくる
まれこのチェックはまさに、alg: "none" や想定外の HS* の値を持つトークンを阻止するためにあります。ログに見慣れないアルゴリズムが現れたら、受け入れて対処すべきバグではなく、プロービング(探りを入れる行為)として扱ってください。
修正方法
- 1.
許可リスト、鍵、発行者の設定をそろえる
まずヘッダーを確認し、3 つすべてを一致させてください。移行期間中は両方のアルゴリズムを一時的に受け入れ、JWKS の kid でそれぞれに専用の鍵を割り当ててください。
js import { decodeProtectedHeader, jwtVerify } from "jose"; console.log(decodeProtectedHeader(token)); // { alg: "ES256", kid: "..." } await jwtVerify(token, jwks, { algorithms: ["ES256"] }); - 2.
許可リストをできるだけ小さく保つ
すべてのアルゴリズムを列挙して、このエラーを「修正」してはいけません。安全な最終形は、トークンの種類ごとに値を 1 つにすることです。RFC 8725(JWT Best Current Practices)も同じことを述べています。
js // good: exactly what your issuer signs with { algorithms: ["ES256"] } // bad: defeats the protection this error provides { algorithms: ["ES256", "RS256", "HS256", "PS256"] }