Modern Frontend CVEs

対象CVE: CVE-2026-42349

[重要] Clerk認証の脆弱性 (CVE-2026-42349) 解説と対応策

Clerkの認証機能において、複数の条件を組み合わせた場合に発生するアクセス制御の脆弱性が報告されました。速やかなアップデート、または回避策の適用を推奨します。

はじめに

Clerkは、モダンなWebアプリケーションに強力な認証・認可機能を提供するサービスとして、多くのフロントエンドプロジェクトで採用されています。しかし先日、Clerkの認証機能において、特定の条件下で誤ったアクセス許可が発生する可能性のある脆弱性(GHSA-w24r-5266-9c3c / CVE-2026-42349)が報告されました。本記事では、この脆弱性の詳細、影響範囲、そして日本のフロントエンドエンジニアが取るべき対応策について解説します。

脆弱性の概要

この脆弱性は、Clerkの認証関数である `has()` や `auth.protect()` を使用する際に、複数の認証条件を同じオブジェクト内で組み合わせてチェックした場合に発生します。具体的には、再認証(`reverification`)とロール・権限などの条件、または課金プラン関連(`feature`/`plan`)とロール・権限などを組み合わせた場合に、本来アクセスを拒否すべきユーザーに対して誤ってアクセスを許可してしまう可能性があります。これにより、認可されていないユーザーが、特定の機能や情報にアクセスできてしまう恐れがあります。

影響を受ける条件と具体例

主に以下のパターンで複数の条件を組み合わせて利用している場合に影響を受けます。

1. `reverification`(再認証)と、`role`(ロール)、`permission`(権限)、`feature`(機能)、`plan`(プラン)のいずれかの条件を組み合わせた場合。 例: `await auth.protect({ permission: 'org:settings:delete', reverification: 'strict' });`

2. 課金関連のチェック(`feature`または`plan`)と、`role`または`permission`を組み合わせた場合。 例: `const canAct = has({ permission: 'org:admin', feature: 'premium' });`

**以下の場合は影響を受けません。** ・単一の条件のみで認証チェックを行っている場合(例: `await auth.protect({ permission: 'org:settings:delete' });`)。 ・`auth.protect()` のコールバック形式で、個々の条件を個別にチェックしている場合(ただし、コールバック内で前述の組み合わせを使用している場合は影響を受けます)。

また、Clerkの`@clerk/nextjs`パッケージには、`auth.protect()`に`unauthenticatedUrl`などの引数と認証パラメータを同じオブジェクトで渡すと、認証パラメータが無視されてしまうという別の問題も存在します。こちらも合わせてご注意ください。

影響範囲と深刻度

この脆弱性は、悪意のあるユーザーがユーザーセッションを乗っ取ったり、他のユーザーになりすましたりするような深刻な影響は報告されていません。影響は認証判断の誤りに限定されており、誤ってアクセスが許可される可能性のある特定の機能や情報へのアクセスに留まります。Clerkの認証ミドルウェアやトークン検証は引き続き正常に機能します。しかし、高リスクに分類されており、認可をバイパスされることで、機密情報の漏洩や不正な操作に繋がりかねないため、速やかな対応が強く推奨されます。

推奨される対応策

この脆弱性への対応は、主にパッケージのアップグレード、または一時的な回避策の適用が挙げられます。

現在使用しているClerkのフレームワークパッケージ(例: `@clerk/nextjs`, `@clerk/remix` など)を、最新のパッチリリースにアップグレードしてください。Clerk Core 2とCore 3の両方にパッチが提供されています。

`@clerk/clerk-js` を直接プロジェクトでピン留めしている場合は、こちらもパッチ適用済みのバージョンにアップグレードが必要です。CDN経由でロードしている場合は、フレームワークパッケージの更新によって自動的に修正が適用されることが多いでしょう。

すぐにパッケージのアップグレードが難しい場合は、以下の回避策を適用してください。複数の条件を組み合わせていた `has()` や `auth.protect()` の呼び出しを、単一の条件チェックに分割して順次実行します。

例えば、以下のコードは脆弱性の影響を受けます。 ```typescript await auth.protect({ permission: 'org:X', reverification: 'strict' }); ```

これを以下のように分割して記述することで、それぞれの単一条件チェックは期待通りに機能し、どちらか一つでも失敗すればアクセスが拒否されるため、正しい結果が得られます。 ```typescript await auth.protect({ reverification: 'strict' }); await auth.protect({ permission: 'org:X' }); ```

まとめ

Clerk認証機能におけるこの脆弱性は、特定の条件下での認可の誤りであり、直接的なセッション乗っ取りなどの危険性はないものの、システムに対する不正アクセスを許す可能性があるため、速やかな対応が求められます。パッケージの最新バージョンへのアップグレードが最も推奨される対策ですが、それが難しい場合は一時的な回避策を適用し、安全を確保してください。この機会に、ご自身のプロジェクトにおける認証・認可ロジックを見直し、より堅牢なシステム構築に役立てていきましょう。

← ブログ一覧に戻る