- MongoBleed (CVE-2025-14847) là một lỗ hổng rò rỉ bộ nhớ nghiêm trọng tồn tại trong mọi phiên bản MongoDB kể từ năm 2017, cho phép kẻ tấn công đọc dữ liệu tùy ý trong bộ nhớ heap của cơ sở dữ liệu
- Lỗ hổng phát sinh do lỗi trong đường xử lý nén zlib, và có thể bị khai thác chỉ bằng cách kết nối tới cơ sở dữ liệu mà không cần xác thực
- Kẻ tấn công có thể gửi yêu cầu nén đã bị thao túng để khiến máy chủ cấp phát một bộ đệm có kích thước sai, từ đó làm lộ bộ nhớ của các tác vụ trước đó (mật khẩu, API key, v.v.) bên trong
- MongoDB đã phát hành bản vá vào ngày 19 tháng 12 năm 2025, nhưng các phiên bản EOL (3.6, 4.0, 4.2) sẽ không được sửa
- Lỗ hổng đã tồn tại suốt 8 năm này ảnh hưởng đến hơn 210.000 instance MongoDB lộ ra Internet, và cả môi trường cloud lẫn on-premise đều cần vá ngay hoặc vô hiệu hóa nén
Tổng quan về MongoBleed
- MongoBleed (CVE-2025-14847) là lỗ hổng được phát hiện trong đường xử lý nén thông điệp zlib 1 của MongoDB, ảnh hưởng đến mọi phiên bản từ năm 2017
- Kẻ tấn công chỉ cần kết nối tới cơ sở dữ liệu mà không cần xác thực là có thể đọc dữ liệu bộ nhớ heap tùy ý
- Các phiên bản hết hỗ trợ (EOL) như MongoDB 3.6, 4.0, 4.2 sẽ không được sửa
- Lỗi này được đưa vào từ một PR vào tháng 5 năm 2017, và được công khai chính thức vào ngày 19 tháng 12 năm 2025
- MongoDB cho biết đã áp dụng bản vá cho mọi instance, bao gồm cả dịch vụ đám mây Atlas
Cấu trúc giao tiếp của MongoDB
- MongoDB sử dụng giao thức TCP riêng thay vì HTTP, và thông điệp được truyền dưới định dạng BSON (Binary JSON)
- Mọi yêu cầu đều được cấu thành bằng lệnh OP_MSG, và khi nén sẽ được bọc trong thông điệp OP_COMPRESSED
- Thông điệp bao gồm các trường như
uncompressedSize, originalOpcode, compressorId
uncompressedSize biểu thị kích thước dự kiến sau khi giải nén
Bước khai thác 1 — Cấp phát bộ đệm sai
- Kẻ tấn công đặt giá trị
uncompressedSize thành lớn quá mức so với thực tế để khiến máy chủ cấp phát bộ đệm lớn
- Ví dụ: khai báo một thông điệp thực tế 1KB thành 1MB
- Máy chủ MongoDB sau khi giải nén không kiểm tra kích thước thực tế mà tin vào kích thước do người dùng chỉ định
- Kết quả là trong bộ nhớ sẽ còn lại cấu trúc dạng
[dữ liệu thực | rác heap không được tham chiếu]
- Do MongoDB dựa trên C++ không khởi tạo bộ nhớ, khu vực này có thể chứa dữ liệu nhạy cảm từ các tác vụ trước đó
- Ví dụ: mật khẩu, session token, API key, dữ liệu khách hàng, cấu hình hệ thống, v.v.
Bước khai thác 2 — Rò rỉ dữ liệu
- Kẻ tấn công gửi đầu vào BSON không hợp lệ để buộc máy chủ phân tích dữ liệu rác trong bộ nhớ như một chuỗi
- Trường đầu tiên của BSON là chuỗi, và tuân theo quy tắc chuỗi kết thúc bằng null (null-terminated string) của ngôn ngữ C
- Nếu kẻ tấn công gửi một chuỗi không có ký tự kết thúc null, máy chủ sẽ đọc sang cả các dữ liệu khác trong bộ nhớ
- Ví dụ:
[ { "a | password: 123\0 | apiKey: jA2sa | ip: 219.117.127.202 ]
- Máy chủ nhận diện đây là trường BSON không hợp lệ và trả về phản hồi lỗi kèm nội dung đó
"errmsg": "invalid BSON field name 'a | password: 123'"
- Lặp lại quá trình này, kẻ tấn công có thể quét toàn bộ bộ nhớ heap và thu thập thông tin nhạy cảm
Tác động và mức độ rủi ro
- Vì xảy ra ở giai đoạn trước xác thực (pre-auth), kẻ tấn công có thể truy cập dữ liệu mà không cần đăng nhập
- Các instance MongoDB lộ ra Internet đối mặt với rủi ro ngay lập tức
- Theo tìm kiếm trên Shodan, có hơn 213.000 instance MongoDB đang công khai
- Đây là lỗ hổng đã tồn tại khoảng 8 năm từ 2017 đến 2025, và do cấu trúc đơn giản nên khả năng bị khai thác thực tế là cao
- MongoDB cho biết “hiện chưa có bằng chứng bị khai thác”, nhưng không công bố lời xin lỗi chính thức hay mốc thời gian chi tiết
Cách giảm thiểu
- Cập nhật lên phiên bản đã vá mới nhất (8.0.17 trở lên)
- Trong ngắn hạn, cũng có thể giảm thiểu bằng cách vô hiệu hóa nén mạng zlib
- Người dùng MongoDB Atlas đã được áp dụng bản vá
Thông tin bổ sung và thảo luận liên quan
- Trưởng nhóm bảo mật của Elastic đã đặt tên ‘MongoBleed’ và công bố PoC (script Python)
- MongoDB và Elastic là đối thủ cạnh tranh trong lĩnh vực tìm kiếm và phân tích
- Tài nguyên liên quan:
Tóm tắt
- MongoBleed là lỗ hổng rò rỉ bộ nhớ phát sinh do lỗi xử lý nén zlib
- Kẻ tấn công có thể lấy được dữ liệu bộ nhớ trước đó (mật khẩu, API key, v.v.) thông qua yêu cầu nén bị thao túng
- Mọi phiên bản MongoDB từ 2017 đến 2025 đều bị ảnh hưởng, và vá lỗi hoặc vô hiệu hóa nén là bắt buộc
- Hơn 210.000 instance lộ ra Internet là đối tượng có thể bị ảnh hưởng
- MongoDB đã phát hành bản vá, nhưng bị chỉ trích vì không hỗ trợ các phiên bản EOL và chậm công bố phản ứng
1 bình luận
Ý kiến trên Hacker News
Nhờ vậy, trong vùng nhớ chưa được khởi tạo sẽ không còn dữ liệu có ý nghĩa bị sót lại
Tôi đã nghĩ sẽ có suy giảm hiệu năng, nhưng trên thực tế không hề có tác động nào có thể đo được
Tôi nghĩ bất kỳ ai dùng ngôn ngữ không an toàn bộ nhớ đều nên làm như vậy. Lỗi của Mongo lần này cũng có lẽ đã có thể được giảm thiểu theo cách đó
Nhờ vậy hiệu quả nén bộ nhớ cao hơn, và trung bình thậm chí còn cải thiện hiệu năng
MALLOC_CONF=opt.junk=freethì malloc sẽ thực hiện hành vi tương tựTức là đã có nhiều implementation cung cấp tính năng này dưới dạng tùy chọn
Nếu cần thêm hiệu năng thì có thể viết allocator tùy biến cho mục đích cụ thể
Làm vậy còn mở ra những tối ưu hóa khác mà allocator hệ thống không thể làm được
0xdbvào vùng nhớ mới cấp phát, và0xdfvào vùng nhớ đã giải phóngNhờ đó có thể nhanh chóng bắt được lỗi use-before-initialization hoặc use-after-free
Đây là thiết lập mặc định
init_on_free=1của kernel hay khôngMongo phát triển trong repo riêng tư nội bộ, rồi dùng Copybara để chuyển commit sang repo công khai
Sự lẫn lộn về ngày tháng là do quá trình này
Tôi sẽ cập nhật bài viết để giải thích điểm này và cả chênh lệch ngày tháng
Cụm Atlas của chúng tôi đã được nâng cấp xong vài ngày trước khi CVE được công bố
Ngày nay hầu hết allocator nên mặc định làm vậy
Chris ở Blink đã cải thiện phần này, và kết quả sau đó lan rộng ra toàn bộ Chromium
Tài liệu liên quan cũng rất thú vị
Bài viết trên blog Chromium
Tài liệu PartitionAlloc
Bên SQL thì hiếm hơn nhưng thỉnh thoảng vẫn có
Triết lý là không cần bận tâm đến schema, durability, đọc/ghi, connectivity hay bất cứ thứ gì
Vì vậy việc người ta cũng không quan tâm đến bảo mật chẳng có gì đáng ngạc nhiên
Kiểu thái độ này dẫn đến suy nghĩ “tiện trước mắt đã”, và cuối cùng kéo theo các vấn đề bảo mật như instance DB công khai
Trên thực tế, việc dùng cả SQL lẫn NoSQL cùng nhau là điều bình thường
NoSQL mạnh ở tính sẵn sàng cao cho dữ liệu quy mô lớn, còn SQL phù hợp để lưu trữ dữ liệu quan hệ
Ví dụ như iMessage hay hệ thống matchmaking của EA cũng dùng NoSQL
Cuối cùng thì cả hai đều cần thiết. Đây không phải quan hệ cạnh tranh mà là bổ sung cho nhau
Ví dụ, PostgreSQL chỉ với cấu hình mặc định cũng có thể giành được quyền trên toàn hệ thống
Vì vậy đa số mọi người đều hiểu rõ mức độ nguy hiểm của việc công khai máy chủ SQL
Cá nhân tôi cũng không muốn dùng, nhưng vẫn có những trường hợp DynamoDB hoặc MongoDB phù hợp về mặt kỹ thuật
Video liên quan
Nhưng buffer overflow vẫn còn tồn tại từ năm 2003 đến giờ
Những vấn đề như vậy sẽ lặp lại mãi mãi nếu không bị chặn ở cấp độ ngôn ngữ
Xin gửi lời cảm thông tới các lập trình viên Mongo
Tôi nghĩ dùng ToroDB hoặc JSONB của PostgreSQL còn tốt hơn