Directusの権限回避脆弱性、12.1.0で修正版が公開
Directusでは、WebSocketのREST機能を公開モードにしていると、未認証の相手がユーザー定義コレクションのデータを読み書き・削除できます。12.1.0へ更新するか、WEBSOCKETS_REST_AUTHをhandshakeかstrictに変えてください。
急ぎ度: 早めに
CVSS v3は8.1、v4は9.2で、該当する設定では未認証のままデータを削除できますが、対象は公開モードのWebSocketを有効にした環境に限られ、修正版12.1.0と設定変更による回避策があります。
関係があるか
Directusを自分たちで運用し、WebSocketを公開モードで使っている環境が対象です。既定のままの設定では、この経路は成り立ちません。
| 製品 | 影響を受ける版 | 修正版 |
|---|---|---|
| Directus(npmパッケージ directus) | 12.1.0より前のすべての版 | 12.1.0(@directus/api 37.0.0) |
確かめ方
- 1Directusの版が12.1.0未満かを確認します。Dockerやnpmのどちらでもイメージのタグやpackageのlockファイルで分かります。
- 2起動時の環境変数(.envやコンテナの設定)で、WEBSOCKETS_ENABLED、WEBSOCKETS_REST_ENABLED、WEBSOCKETS_REST_AUTHの値を確認します。WEBSOCKETS_REST_AUTHがpublicなら該当します。
- 3リバースプロキシやファイアウォールの設定から、WebSocketのエンドポイントがインターネットや信頼できない社内網から届くかを確認します。
- 4Directusの提供元が運用するサービスを使っている場合は、提供元の告知で対応状況を確認します。
何が起きたか
Directusで、WebSocketのREST機能を公開モードにしていると、認証に失敗した接続が権限チェックを受けないまま操作できる状態になります。公開ロールに許された範囲を超えて、ユーザー定義コレクションのレコードを読み、作成し、更新し、削除できます。
原因は、認証失敗時の扱いです。失敗した接続では、公開ロールの権限情報が空(null)に置き換わったまま接続が残ります。Directusではnullを内部の信頼された呼び出し用の状態として扱い、サービス層が権限の評価そのものを飛ばします。認証に成功するより失敗するほうが強い権限を得る、という逆転が起きていました。CWEの分類はCWE-636です。
なかでも影響が大きいのは、条件を指定した一括削除です。1回の要求でコレクションの全行を選べて、既定ではバッチ変更の上限もありません。
GitHubの勧告は2026年8月5日付です。CVE番号の公表は11月11日で、勧告から約3か月後になります。
攻撃の流れ
-
1
公開接続
攻撃者が公開モードのWebSocketエンドポイントに接続し、公開ロールとして扱われます。
-
2
認証の失敗
認証に失敗すると、公開ロールの権限情報が空に置き換わり、接続は開いたまま残ります。
-
3
権限評価の省略
以降の操作は内部呼び出しと同じ扱いになり、権限チェックが行われません。
-
4
データの読み書き
ユーザー定義コレクションの内容が読み出され、書き換えられ、削除されます。
どう悪用されるか
認証は不要で、ネットワーク越しにWebSocketのエンドポイントへ届けば試せます。利用者の操作も要りません。ただし、次の設定がすべてそろった環境に限られます。
- WEBSOCKETS_ENABLEDがtrue(既定はfalse)
- WEBSOCKETS_REST_ENABLEDがtrue(WebSocketを有効にすると既定でtrue)
- WEBSOCKETS_REST_AUTHがpublic(既定はhandshake)
- 攻撃者がエンドポイントに到達できる
WEBSOCKETS_REST_AUTHがhandshakeかstrictなら、認証に失敗した時点で接続が閉じるので、この経路は使えません。公開モードの接続でアクセストークンの期限が切れ、再認証に成功しなかった場合も同じ状態になります。意図的に不正なトークンを送られなくても、危険な状態に入りうるということです。
被害は、ユーザー定義コレクションのデータの漏えい、改ざん、削除です。クエリの上限設定やMAX_BATCH_MUTATIONは被害の広がりを抑えるだけで、認可の代わりにはなりません。一方で、directus_で始まるシステムコレクション(users、sessions、tokens、permissionsなど)はこの経路では扱えません。認証情報、セッショントークン、権限の設定は、この脆弱性から直接は漏れないと勧告に書かれています。
今すぐやること
-
1
WebSocket関連の設定を確認する
本番とステージングの両方で、WEBSOCKETS_REST_AUTHがpublicになっていないかを調べます。コンテナ運用なら、起動時に渡している環境変数の定義を見ます。
env | grep WEBSOCKETS -
2
Directusを12.1.0以降に更新する
認証失敗とトークン期限切れのあとも公開ロールの権限情報を保つように変わり、WebSocketの認証モードにかかわらず直ります。12.1.0にはAPIの削除など互換性に影響する変更も含まれるため、リリースノートを読み、検証環境で動作を確かめてから本番に当ててください。
-
3
公開モードで運用していた期間のデータを点検する
該当する設定だった環境では、ユーザー定義コレクションに身に覚えのない削除や更新がないかを、データベースのバックアップ、アプリケーションのログ、リバースプロキシのログと突き合わせて調べます。
-
4
WebSocketの公開範囲を見直す
公開モードが本当に必要かを使う側と確認し、不要なら認証が必要なモードに切り替えたまま運用します。
すぐ更新できないとき
すぐに更新できないときは、WEBSOCKETS_REST_AUTHをhandshakeかstrictにするか、WEBSOCKETS_ENABLEDをfalseにしてWebSocketのエンドポイント自体を無効にします。どちらの設定でも、認証失敗時に接続が閉じるか、エンドポイントが使えなくなるかのため、この経路は塞がります。公開モードの接続に頼っているクライアントがある場合は、設定変更後に動かなくなるかもしれないので、先に利用状況を確認してください。
背景
Directusは、既存のデータベースに管理画面とAPIを付けるオープンソースのデータプラットフォームです。コンテンツ管理や社内ツールの裏側でデータを保持することが多く、REST、GraphQL、WebSocketでデータを公開します。WebSocketは画面の更新を即時に反映する用途などで使われます。
今回の問題は、権限情報がないことを内部呼び出し用の特別な状態として扱う設計が、認証失敗の処理と衝突したことから生じています。公開モードで失敗した接続が、権限の弱いクライアントではなく、信頼された内部呼び出しとして扱われました。12.1.0のリリースノートには、このほかにもGraphQLのWebSocketでの権限情報の上書き、MailServiceのテンプレート読み込み、favicon生成に関するXSSなど、セキュリティ関連の修正が含まれています。更新の理由はこの1件にとどまりません。
よくある質問
Q.12.1.0へ更新すると、既存の機能に影響しますか。
この記事は、取得元の公開情報をもとに、人が監修しながらAIを活用して執筆しています。執筆と監修は佐々木 航が担い、公開したあとも人が内容を確認しています。誤りに気づいたときは直し、記事の末尾に訂正の行を残します。対応を決める前に、下の原文と参照先も確認してください。
影響パッケージ
| パッケージ | 影響を受ける版 → 修正版 | |
|---|---|---|
| directusdirectus |
12.1.0 未満→ 12.1.0 |
12.1.0 |
原文の説明 取得元が公開している説明をそのまま載せています (多くは英語)。
Directus before 12.1.0 contains an authorization bypass vulnerability that allows unauthenticated attackers to skip permission checks by sending a failed auth message on public-mode WebSocket connections. Attackers can send an invalid token so handleAuthRequest sets accountability to null, then read, create, update or delete records in any user-defined collection.
出典: CVE.org (CVE Program・cvelistV5) NVD GitHub Advisory
参照URL
- advisory github.com
- advisory github.com
- advisory vulncheck.com
- advisory nvd.nist.gov
- advisory github.com
- package github.com
- patch github.com
- web github.com
- web github.com