MongooseのcountDocumentsに脆弱性、修正版あり
MongooseのcountDocuments()で、設定したsanitizeFilterが適用されない脆弱性です。npmのmongooseを使い、外部からの値を条件に渡すアプリが関係します。使用中の版を調べ、修正版へ更新してください。
急ぎ度: 早めに
CVSS v3は9.8で、4つの系統すべてに修正版が出ていますが、公開されている説明が挙げる影響は件数の誤りと、その件数に頼る処理の回避にとどまるためです。
関係があるか
npmのmongooseを使い、sanitizeFilterを有効にしたうえで、外部から入る値をcountDocuments()の条件に渡しているアプリが対象です。ページ送りの総件数や、件数による権限判定を持つ業務システムやWebサービスでは影響が大きくなります。
| 製品 | 影響を受ける版 | 修正版 |
|---|---|---|
| mongoose 6系 | 6.13.11より前 | 6.13.11 |
| mongoose 7系 | 7.0.0以上7.8.12未満 | 7.8.12 |
| mongoose 8系 | 8.0.0以上8.24.3未満 | 8.24.3 |
| mongoose 9系 | 9.0.0以上9.9.2未満 | 9.9.2 |
確かめ方
- 1プロジェクトごとにmongooseの版を調べます。直接の依存だけでなく、ほかのパッケージ経由で入っている版も見ます。
- 2ソースコードでcountDocuments(の呼び出しと、sanitizeFilterの設定(クエリ、接続、グローバルのどれか)を検索します。
- 3非推奨のcount()も同じ修正の対象に含まれているため、使っていればあわせて洗い出します。
- 4countDocuments()の条件に、リクエストのパラメーターや本文の値がそのまま入っていないかを確認します。
何が起きたか
Mongooseで、クエリの条件を検査するsanitizeFilterが、件数を数えるcountDocuments()にだけ適用されない脆弱性が見つかりました。外部から入った値が単なる文字列ではなく検索の演算子として扱われ、本来は一致しない文書まで件数に含まれることがあります。
sanitizeFilterは、クエリセレクターの注入を防ぐためのMongooseの仕組みです。古い版ではcountDocuments()の処理でこの検査を通していませんでした。分類はCWE-943です。
件数をもとに認可やアプリの分岐を決めている場合は、その判断が狂うおそれがあります。
修正の変更は、countDocuments()に加えて非推奨のcount()とカーソルの処理にもsanitizeFilterを通すものです。GitHubの勧告は2026年11月2日付で、CVEは11月9日に公表されました。
攻撃の流れ
-
1
入力を渡す
外部から入った値が、countDocuments()の検索条件にそのまま渡されます。
-
2
検査が働かない
有効にしたsanitizeFilterが、件数を数える処理では適用されません。
-
3
演算子として解釈
渡された値が文字列ではなく、検索の演算子として処理されます。
-
4
件数がずれる
一致しないはずの文書が数に入り、件数に頼る判断が狂います。
どう悪用されるか
CVSS v3のベクターでは、ネットワーク経由で、認証も利用者の操作も要らず、複雑な手順もないとされています。ただし実際に影響が出るのは、sanitizeFilterを有効にしたアプリが、外部から操作できる値をcountDocuments()の条件に渡している場合です。
起きるのは、一致しないはずの文書が件数に入ることです。そのため、件数をもとにした認可やアプリの処理が崩れるおそれがあります。CVSSは機密性・完全性・可用性をいずれも高としていますが、説明にある影響は件数の誤りです。実際の被害は、アプリが件数に何を任せているかで変わると考えられます。
今すぐやること
-
1
使用中の版を洗い出す
mongooseを使うプロジェクトすべてで版を調べ、修正前の範囲に入るものを一覧にします。ロックファイルに残っている版も見ます。
npm ls mongoose -
2
修正版へ更新する
使っている系統に合わせて、6.13.11、7.8.12、8.24.3、9.9.2のいずれかに更新します。勧告では、サポート中のすべての系統に修正版が出たとされています。更新後は、countDocuments()を使う画面とAPIの動作を確認します。
-
3
件数に頼る処理を点検する
件数だけで権限や処理の可否を決めている箇所がないかを見直します。古い版を動かしていた期間に、条件に不自然な値が入った記録がないかもログで確認します。
-
4
ベンダーの告知で最新を確認する
MongooseのGitHubにある勧告と各版のリリースノートで、更新内容と追加情報を確認します。
すぐ更新できないとき
すぐに更新できないときは、勧告にある回避策としてミドルウェアを入れる方法があります。countDocuments()の実行前に呼ばれる処理(pre)を追加し、その中でmongoose.sanitizeFilter(this.getFilter())を呼んで、検査を必ず通します。プラグインとして全スキーマに入れる形が勧告で示されており、モデルの定義より前に登録しておきます。回避策は更新までのつなぎで、更新は別途必要です。
背景
MongooseはNode.jsからMongoDBを扱うためのライブラリーで、Webアプリのデータ層として、ユーザー情報や業務データの検索・集計を受け持ちます。countDocuments()は、一覧画面の総件数や、条件に合う文書があるかの判定によく使われます。
sanitizeFilterは、検索条件に紛れ込んだ演算子を無害にする機能です。有効にすると、演算子を含むオブジェクトは$eqで包まれ、文字列の項目では型変換の段階でCastErrorになります。$whereは拒否されます。意図して演算子を渡したい場合はmongoose.trusted()で明示します。今回の修正テストには、クエリ単位の設定のほかに、接続に設定した場合も入っています。守りを入れたつもりで件数の処理だけ素通りしていたため、設定の有無を見ても安全とは言えない脆弱性です。
よくある質問
Q.sanitizeFilterを接続やグローバルで設定している場合も対象ですか。
Q.sanitizeFilterを有効にしていないアプリは安全ですか。
この記事は、取得元の公開情報をもとに、人が監修しながらAIを活用して執筆しています。執筆と監修は佐々木 航が担い、公開したあとも人が内容を確認しています。誤りに気づいたときは直し、記事の末尾に訂正の行を残します。対応を決める前に、下の原文と参照先も確認してください。
影響パッケージ
| パッケージ | 影響を受ける版 → 修正版 | |
|---|---|---|
| Automatticmongoose | — | 記載なし |
| npmmongoose |
9.0.0 以上 9.9.2 未満→ 9.9.2 |
9.9.2 |
原文の説明 取得元が公開している説明をそのまま載せています (多くは英語)。
Impact
sanitizeFilter is Mongoose's mechanism for protecting against query selector injection attacks. In older versions of Mongoose, sanitizeFilter was not applied for countDocuments() queries.
Patches
Patches have been released for all supported Mongoose major release lines. Please upgrade to the following versions depending on which major version of Mongoose applications are using.
^9.9.2^8.24.3^7.8.12^6.13.11
Workarounds
Middleware:
mongoose.plugin(function() {
schema.pre('countDocuments', function() {
// This will always apply `sanitizeFilter` on `countDocuments`
mongoose.sanitizeFilter(this.getFilter());
});
});
出典: CVE.org (CVE Program・cvelistV5) NVD GitHub Advisory
参照URL
- advisory github.com
- advisory nvd.nist.gov
- package github.com
- web github.com
- web github.com
- web github.com
- web github.com
- web github.com
- web github.com
- web github.com
- web github.com
- web github.com
- web github.com