JWTの'none'アルゴリズムの使用

JWTのnoneアルゴリズムの使用

説明

noneは署名のないJWTを表します。外部から受け取ったこのトークンを認証・認可の根拠にすると、攻撃者が内容を偽造して認証を回避したり、他の利用者になりすましたりするおそれがあります。

想定される影響

  • 攻撃者が偽造したトークンで認証を通過する可能性があります。
  • 保護すべき利用者データやセッション情報が漏えいするおそれがあります。

対処方法

  • 認証・認可用のトークンは、信頼できる鍵と、サーバー側で許可したHS256やRS256などのアルゴリズムで検証してください。
  • 署名のないnoneトークンを認証の根拠にしないでください。
  • 発行者、対象、有効期限の条件と、利用者のアクセス権限も確認してください。

例

従来のjose 1.28.2 APIを説明する抜粋です。新しい実装では保守されているバージョンのAPIを使ってください。token-hereは実際のトークンに置き換えてください。変更後のJWT_SECRETは、信頼できる経路で供給した256ビット以上のランダムな共有秘密鍵をBase64で表した値です。設定の欠落・不備と検証エラーの処理は省略しています。HS256では公開鍵ではなく共有秘密鍵を使います。

変更前

javascript
const jose = require("jose");
const { JWK, JWT } = jose;
// 署名のない'none'アルゴリズムを受け入れる
const token = JWT.verify('token-here', JWK.None);

変更後

javascript
const jose = require("jose");
const { JWK, JWT } = jose;
const secretKey = JWK.asKey(Buffer.from(process.env.JWT_SECRET, 'base64'));
// 許可したHS256アルゴリズムと共有秘密鍵で検証
const token = JWT.verify('token-here', secretKey, { algorithms: ['HS256'] });

変更前はJWK.Noneにより署名のないトークンを明示的に受け入れます。変更後は共有秘密鍵を使い、HS256だけで署名を検証します。正しい鍵で検証に成功したトークンだけを使い、サービスに必要なクレームやアクセス権限は別途確認してください。

参考資料