
PoC for CVE-2025-65945 (node-jwsにおける暗号署名の不適切な検証)
これは、node-jws ライブラリにおける署名検証バイパスの概念実証です。このバグにより、サーバーがユーザー制御のデータから HMAC 秘密鍵を導出する場合、攻撃者は有効な JWT を偽造できます。
jws.createVerify() 関数は、HMAC アルゴリズムを使用する際に秘密鍵が実際に提供されたことを検証しません。アプリが JWT 内の何か(kid ヘッダーなど)に基づいて秘密鍵を検索し、その検索が失敗した場合、空の秘密鍵に対して検証してしまう可能性があります。
攻撃者はこれを次のように悪用できます:
undefined を返し、それが空文字列に変換される攻撃者は、任意のユーザーになりすましたり、自身に管理者権限を付与したりできるようになります。
修正するには、3.2.3+ または 4.0.1+ にアップグレードしてください。
Bun がインストールされていることを確認してから、以下を実行してください:
# Install the vulnerable version
bun install [email protected]
# Run the exploit
bun run exploit.js
偽造された管理者トークンが有効として受け入れられる出力が表示されるはずです。
この PoC は、以下のようなサーバーをシミュレートします:
kid(キー ID)ヘッダーに基づいて秘密鍵を検索するcreateVerify() を使用する攻撃者は kid: "non-existent-key" を持つ JWT を作成し、空の秘密鍵で署名します。サーバーがこのキーを検索しようとすると undefined が返され、検証ストリームに空文字列が書き込まれ、偽造トークンが検証を通過します。
# Upgrade to patched version
bun install [email protected]
# Run again - should fail now
bun run exploit.js
パッチ適用版では、エラーが表示されます: secret must be a string or buffer or a KeyObject。修正により、HMAC 操作を実行する前に適切な秘密鍵が設定されていることが検証されます。
あなたのコードが次のような場合、影響を受ける可能性があります:
const decoded = jws.decode(token);
const secret = lookupSecret(decoded.header.kid); // might return undefined!
const verifier = jws.createVerify({
algorithm: "HS256",
signature: token,
});
verifier.secret.write(secret); // oops
verifier.secret.end();