- MongoBleed(CVE-2025-14847) は、2017年以降のすべての MongoDB バージョン に存在していた深刻なメモリリーク脆弱性で、攻撃者がデータベースの ヒープメモリ内の任意データ を読み取ることが可能
- この脆弱性は zlib 圧縮経路のバグ によって発生し、認証なしで単にデータベースへ接続するだけで悪用可能
- 攻撃者は 細工された圧縮リクエスト を送り、サーバーが誤ったサイズのバッファを割り当てるよう誘導し、その中に残る 以前の処理のメモリ(パスワード、API キーなど) を露出させられる
- MongoDB は 2025年12月19日にパッチを配布したが、EOL バージョン(3.6、4.0、4.2) は修正されていない
- 8年間存在していたこの脆弱性は、インターネットに公開された21万台超の MongoDB インスタンス に影響し、クラウド・オンプレミス環境の両方で 即時のパッチ適用または圧縮無効化 が必要
MongoBleed の概要
- MongoBleed(CVE-2025-14847) は、MongoDB の zlib 1 メッセージ圧縮経路 で見つかった脆弱性で、2017年以降のすべてのバージョンに影響する
- 攻撃者は認証なしでデータベースに接続するだけで 任意のヒープメモリデータ を読み取れる
- MongoDB 3.6、4.0、4.2 などの サポート終了(EOL) バージョンは修正されていない
- このバグは 2017年5月の PR で導入され、2025年12月19日 に正式公開された
- MongoDB は Atlas クラウドサービス を含むすべてのインスタンスにパッチを適用したと発表した
MongoDB の通信構造
- MongoDB は HTTP ではなく独自の TCP プロトコル を使用し、メッセージは BSON(Binary JSON) 形式で送信される
- すべてのリクエストは OP_MSG コマンドで構成され、圧縮時は OP_COMPRESSED メッセージで包まれる
- メッセージには
uncompressedSize、originalOpcode、compressorId などのフィールドが含まれる
uncompressedSize は展開後の想定サイズを表す
エクスプロイト段階 1 — 誤ったバッファ割り当て
- 攻撃者は
uncompressedSize の値を実際より 過度に大きい値 に設定し、サーバーに大きなバッファを割り当てさせる
- 例: 実際は 1KB のメッセージを 1MB として宣言
- MongoDB サーバーは展開後に 実際のサイズを検証せず、ユーザーが指定したサイズを信頼する
- その結果、メモリには
[実データ | 未参照のヒープゴミ] のような構造が残る
- C++ ベースの MongoDB はメモリ初期化を行わないため、この領域には 以前の処理の機微データ が含まれる可能性がある
- 例: パスワード、セッショントークン、API キー、顧客データ、システム設定など
エクスプロイト段階 2 — データ漏えい
- 攻撃者は 不正な BSON 入力 を送信し、サーバーがメモリ中のゴミデータを文字列としてパースするよう誘導する
- BSON の最初のフィールドは文字列であり、C 言語の ヌル終端文字列(null-terminated string) ルールに従う
- 攻撃者が ヌル終端文字のない文字列 を送ると、サーバーはメモリ内の別データまで読み込んでしまう
- 例:
[ { "a | password: 123\0 | apiKey: jA2sa | ip: 219.117.127.202 ]
- サーバーはこれを不正な BSON フィールドとして認識し、エラーメッセージにその内容を含めて応答する
"errmsg": "invalid BSON field name 'a | password: 123'"
- この過程を繰り返すことで、攻撃者は ヒープメモリ全体をスキャン しながら機微情報を収集できる
影響と危険性
- 認証前(pre-auth)段階 で発生するため、攻撃者はログインなしでデータにアクセスできる
- インターネットに公開された MongoDB インスタンス は直ちに危険にさらされる
- Shodan 検索ベースで 213,000台以上 の MongoDB インスタンスが公開状態
- 2017年から2025年まで約8年間 存在した脆弱性であり、構造が単純なため実際に悪用される可能性が高い
- MongoDB は「現時点で悪用の証拠はない」と述べたが、公式な謝罪や詳細なタイムラインは公開していない
緩和策
- 最新のパッチバージョン(8.0.17 以上) に更新する
- 短期的には zlib ネットワーク圧縮の無効化 でも緩和可能
- MongoDB Atlas ユーザーにはすでにパッチが適用済み
追加情報と関連議論
- Elastic のセキュリティチームリードが 「MongoBleed」 という名前を付け、PoC(Python スクリプト) を公開した
- MongoDB と Elastic は 検索および分析機能 の分野で競合関係にある
- 関連リソース:
要約
- MongoBleed は zlib 圧縮処理バグ により発生した メモリリーク脆弱性
- 攻撃者は 細工された圧縮リクエスト を通じて 以前のメモリデータ(パスワード、API キーなど) を取得できる
- 2017〜2025年のすべての MongoDB バージョン が影響を受け、パッチ適用または圧縮無効化 が必須
- インターネット公開インスタンス21万台超 が潜在的な被害対象
- MongoDB はパッチを配布したが、EOL バージョン非対応と公開対応の遅れ が指摘されている
1件のコメント
Hacker News の意見
そのおかげで、未初期化メモリに意味のあるデータが残らないようになった
性能低下を予想していたが、実際には 測定可能な影響はまったくなかった
メモリ安全でない言語を使う人は皆こうすべきだと思う。今回の Mongo のバグもこの方法で緩和できたはずだ
そのおかげでメモリ圧縮の効率が上がり、平均的にはむしろ性能が向上するという
MALLOC_CONF=opt.junk=free環境変数を設定すると malloc が同じ動作を行うつまり、すでに多くの実装がこうした機能をオプションとして提供している
さらに性能が必要なら、特定用途向けにカスタムアロケータを書けばよい
システムアロケータでは不可能な別の最適化も可能になるはずだ
0xdb、解放済みメモリを0xdfで埋めるそのおかげで use-before-initialization や use-after-free バグを素早く見つけられる
これがデフォルト設定になっている
init_on_free=1オプションを有効にするのと同じ動作なのだろうかMongo は内部の 非公開リポジトリ で開発した後、Copybara を通じて公開リポジトリへコミットを移している
日付の混乱はこの過程で生じたものだ
記事を更新して、この事実と日付の差を説明する予定だ
私たちの Atlas クラスター は CVE が公開される数日前にすでにアップグレードを完了していた
今ではほとんどのアロケータがデフォルトでそうすべきだ
Blink では Chris がこの部分を改善し、その結果が Chromium 全体に広がった
関連文書も興味深い
Chromium ブログ記事
PartitionAlloc ドキュメント
SQL 側では珍しいが、たまにある
スキーマ、耐久性、読み書き、接続性など何も気にしなくていいという思想だ
だからセキュリティも気にしないことに驚きはない
こうした態度は「今この瞬間だけ楽をしたい」という発想につながり、最終的には 公開 DB インスタンス のようなセキュリティ問題に結びつく
実際には SQL と NoSQL を併用する のが一般的だ
NoSQL は大規模データの高可用性に強みがあり、SQL はリレーショナルデータの保存に適している
たとえば iMessage や EA のマッチメイキングシステムも NoSQL を使っている
結局は両方必要だ。競争関係ではなく 補完関係 だ
たとえば PostgreSQL はデフォルト設定だけでもシステム全体の権限を持ち得る
だから大半の人は公開 SQL サーバーの危険性をよく理解している
個人的には使いたくないが、DynamoDB や MongoDB が技術的に適しているケースもある
関連動画
だがバッファオーバーフローは 2003 年から今なお存在している
こうした問題は言語レベルで防がない限り永遠に繰り返される
Mongo の開発者たちに慰めを送りたい
むしろ ToroDB や PostgreSQL の JSONB を使うほうがよいと思う