[Auth.js/NextAuth.js] getToken()におけるサービス拒否の脆弱性(GHSA-xmf8-cvqr-rfgj)について
はじめに
Auth.jsおよびNextAuth.jsを使用しているフロントエンドエンジニアの皆さん、こんにちは。今回は、Auth.jsの内部で使用されている`getToken()`ヘルパーに存在するサービス拒否(DoS)の脆弱性(GHSA-xmf8-cvqr-rfgj)について解説します。この脆弱性は、不正な入力が原因でサーバーサイドの処理がクラッシュする可能性があるため、特にAPIルートやミドルウェアで`getToken()`を直接利用している場合に注意が必要です。
脆弱性の概要と仕組み
この脆弱性は、`next-auth/jwt`や`@auth/core/jwt`からエクスポートされている`getToken()`ヘルパーが、不正な形式の`Authorization: Bearer …`ヘッダーを読み取った際に、捕捉されない例外をスローすることが原因で発生します。
通常、`getToken()`はセッションクッキーが存在しない場合、Bearerトークンの値をURLデコードしようとします。ここで、パーセントエンコーディングが不正な形式であると、デコード処理が例外をスローします。この例外が`getToken()`の呼び出し元で適切に処理(`try/catch`でラップ)されていない場合、アプリケーション全体がクラッシュし、サービス拒否の状態に陥る可能性があります。
これは、CWE-20: Improper Input Validation(不適切な入力検証)に分類される問題です。
あなたが影響を受けるかどうかの確認
以下のすべての条件に当てはまる場合、あなたは影響を受けます。
1. `next-auth`バージョン`5.0.0-beta.25`以前、または同じ`getToken()`実装を公開する`@auth/core`を使用している。 2. アプリケーションで`getToken()`を直接呼び出している(例:Route Handler、ミドルウェア、サーバーサイドのRequest Handler)。 3. `getToken()`の呼び出しを独自の`try/catch`でラップしていない。
以下の場合は影響を受けません。
1. フレームワークの`auth()`ヘルパーのみを使用し、`getToken()`を直接呼び出していない場合。 2. すべての`getToken()`呼び出し箇所がすでに例外処理(`try/catch`)で保護されている場合。
Next.jsのApp Routerで`auth()`を使用している場合や、Pages Routerで`getServerSession()`を使用している場合など、直接`getToken()`を呼び出していない場合は通常影響を受けません。しかし、もしカスタムでJWTを扱うために`getToken()`を直接呼び出している場合は注意が必要です。
具体的な影響
サービス拒否(Denial of Service, DoS): 認証されていないリクエストであっても、不正な`Authorization: Bearer`ヘッダーを送信するだけで、`getToken()`を呼び出しているハンドラーで未処理の例外が発生し、アプリケーションがクラッシュする可能性があります。これは、単一の不正なリクエストがサービス停止を引き起こす可能性があることを意味します。
この脆弱性は、トークンやセッション、その他のデータの漏洩には繋がりません。また、認証をバイパスすることもありません。影響はリクエスト単位であり、可用性に限定されます。
対策
最も推奨される対策は、パッチが適用されたバージョンへのアップグレードです。
Auth.jsまたはNextAuth.jsのパッチ適用版がリリースされ次第、速やかにアップグレードしてください。(執筆時点ではまだリリースされていませんが、アドバイザリが更新される予定です。)
修正版では、不正なBearer値は無効なトークンとして扱われ、`null`が返されるようになります。アップグレード後、コード変更は不要です。
コードレベルでの対応: `getToken()`の呼び出しを`try/catch`ブロックでラップし、エラーが発生した場合は「トークンなし」として扱うようにします。
```ts let token = null; try { token = await getToken({ req, secret }); } catch (e) { // エラーが発生した場合もトークンがないものとして扱う console.error("Failed to get token:", e); // 必要に応じてログを出力 token = null; } ```
エッジレベルでの対応: プロキシやミドルウェアなどで、`Authorization`ヘッダーのBearer部分が有効なパーセントエンコーディングでない場合に、そのヘッダーを削除または正規化する、あるいはリクエストを拒否する処理を追加します。
まとめ
Auth.js/NextAuth.jsの`getToken()`を使用している場合、不正なBearerヘッダーによるサービス拒否の脆弱性に注意が必要です。特にAPIルートやミドルウェアで`getToken()`を直接利用し、`try/catch`で囲んでいない場合は、早急な対応が求められます。
まずはご自身のアプリケーションが影響を受けるか確認し、パッチ適用版へのアップグレード、またはワークアラウンドの実装を検討してください。最新のライブラリに保ち、適切なエラーハンドリングを行うことが、堅牢なアプリケーション開発には不可欠です。