MongoBleed(CVE-2025-14847): 8년간 숨겨져 있던 치명적 MongoDB 메모리 유출 취약점
개요
2025년 말, MongoDB에서 장기간 잠복해 있던 고위험(High) 수준의 메모리 정보 노출 취약점이 공개되었다. MongoBleed로 이름 붙여진 이 취약점은 인증하지 않은 상태에서 초기화되지 않은 힙 메모리를 읽을 수 있고, 이로 인해 민감 정보가 유출될 수 있다. 또한 CISA는 이 취약점을 KEV 목록에 등재하며 실제 악용 정황이 있음을 전제로 신속한 대응을 권고했다.
본 글은 MongoBleed(CVE-2025-14847)의 발생 원리와 공격 흐름을 정리하고, 8년간 발견되지 못한 이유와 해당 취약점의 대응 방안을 소개한다.
기술 배경
1. MongoDB 와이어 프로토콜과 메시지 압축
MongoDB는 클라이언트-서버 간 통신에 HTTP 대신 자체 바이너리 프로토콜인 MongoDB 와이어 프로토콜(Wire Protocol)을 사용한다. 기존에는 OP_QUERY, OP_INSERT 등 다양한 opcode를 사용했으나, MongoDB 5.1 이후 대부분의 작업이 OP_MSG로 통합되었다. OP_MSG는 BSON 형식의 페이로드를 전송하는 확장 가능한 메시지 포맷이다.
2017년 MongoDB 3.6부터 zlib 메시지 압축 기능이 도입되어 네트워크 전송량을 줄일 수 있는 선택지가 확대되었다. MongoDB는 snappy, zlib, zstd 세 가지 압축 알고리즘을 지원하는데, 클라이언트와 서버는 핸드셰이크 과정에서 사용할 알고리즘을 협상한다. 압축이 활성화되면 기존 메시지가 OP_COMPRESSED 메시지로 래핑되어 전송된다.

OP_COMPRESSED 메시지에는 MsgHeader(16바이트), originalOpcode(4바이트), uncompressedSize(4바이트), compressorId(1바이트), 그리고 압축된 페이로드가 포함된다. uncompressedSize 필드 값을 검증 없이 신뢰하기 때문에, 해당 값을 그대로 활용하게 되면 실제 데이터보다 큰 메모리 버퍼를 할당시킬 수 있게 된다.
2. BSON 형식과 파싱 메커니즘
BSON(Binary JSON)은 MongoDB의 기본 데이터 형식으로 JSON-like 문서를 바이너리로 직렬화한 포맷이며, 필드명(element name)은 null-terminated 문자열(cstring)로 표현된다.

MongoDB 서버는 BSON 데이터를 메모리에서 순차적으로 파싱한다. 파서는 먼저 문서의 전체 크기를 읽고 각 필드를 하나씩 읽어나가는데, 각 필드를 읽을 때 타입 바이트를 확인한 후 null terminator를 찾을 때까지 필드명을 읽는다. 파싱 과정에서 예상치 못한 데이터 구조를 만나면 MongoDB는 파싱을 중단하고 에러를 반환하며, 에러 메시지에는 문제가 발생한 필드명이 포함될 수 있다.
CVE-2025-14847 취약점 원인
MongoBleed 취약점은 src/mongo/transport/message_compressor_zlib.cpp 파일의 ZlibMessage Compressor::decompressData() 함수의 길이 처리 로직 문제와 BSON 파싱 과정의 연계로 발생한다. 각 문제의 원인을 살펴보자.
1. decompressData

이 함수는 OP_COMPRESSED 메시지를 수신했을 때 압축된 데이터를 해제하는 역할을 한다. 함수는 두 개의 매개변수를 받는다. input은 압축된 데이터를 담고 있는 ConstDataRange 객체이고, output은 압축 해제된 데이터를 저장할 버퍼인 DataRange 객체이다.
함수는 먼저 length 변수를 선언하고 output.length()로 초기화한다. 여기서 output.length()는 할당된 버퍼의 전체 크기를 반환한다. 그 다음 zlib의 uncompress() 함수를 호출하여 실제 압축 해제를 수행한다.
uncompress() 함수의 시그니처는 int uncompress(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen)이다. destLen은 입출력 매개변수(in-out parameter)로, 호출 전에는 dest 버퍼의 할당 크기를 나타내고, 호출 후에는 실제로 압축 해제된 데이터의 크기로 업데이트된다.
핵심 결함은 함수의 반환값 처리에 있다. decompressData() 함수는 uncompress()가 업데이트한 length 값이 아니라, 원래 할당된 버퍼 크기인 output.length() 값을 반환한다.
2. BSON 파싱과 메모리 유출
decompressData() 함수가 잘못된 크기를 반환하면, 초기화되지 않은 메모리가 포함된 큰 버퍼의 데이터가 유효한 데이터로 취급된다. 공격자는 OP_COMPRESSED 메시지의 uncompressedSize 필드를 조작하여 서버가 실제 데이터보다 큰 버퍼를 할당하도록 만든다.
정상적인 경우 필드명은 유효한 데이터 영역 내에서 null terminator로 끝나지만, 반환된 버퍼 크기가 잘못된 경우 파서는 유효한 데이터 경계를 넘어 초기화되지 않은 메모리 영역까지 읽게 된다. 이 초기화되지 않은 메모리에는 이전에 힙에 있던 문자열/조각이 남아 있을 수 있으며, 파서는 이를 필드명으로 인식하려고 시도한다.
초기화되지 않은 메모리에서 우연히 null 바이트를 만나면, 파서는 그 지점까지의 바이트들을 필드명으로 인식한다. BSON 구조가 유효하지 않으므로 파싱이 실패하고, MongoDB는 에러 메시지를 생성하는데, 이 에러 메시지에는 유출된 메모리 내용이 포함된다. 공격자는 이러한 에러 응답을 반복적으로 수집하여 서버 메모리의 민감한 정보를 획득할 수 있다.
공격 시나리오

취약한 MongoDB 인스턴스를 전제로 공격이 이뤄질 경우 [그림 4]와 같이 데이터 유출이 발생할 수 있다. 공격자는 zlib 기반 OP_COMPRESSED 메시지의 길이/헤더 값을 비정상적으로 구성한 조작 패킷을 인증 없이 전송한다. 서버는 인증 처리 이전 단계에서 이를 압축 해제 로직으로 처리하며, 이 과정에서 헤더의 길이 정보와 실제 처리 길이의 불일치로 인해 “실제 압축 해제된 데이터 길이”와 “할당된 버퍼 길이”가 어긋나는 오류 조건이 발생한다.
그 결과 서버가 유효 데이터 길이보다 큰 길이를 후속 처리에 사용하게 되며, 버퍼의 남는 영역에 존재하던 초기화되지 않은 힙 메모리 조각이 응답 경로로 섞여 클라이언트에 노출될 수 있다. 노출되는 데이터는 단발성으로는 단편일 수 있으나, 공격 시도 과정에서 민감 정보(예시 : 토큰, 키, 자격증명 등)의 일부가 조각 형태로 유출될 가능성이 존재한다.
실제로 2025년 12월 말, 한 대형 온라인 게임 서비스 사업자에서 계정/운영 시스템 이상 징후와 서비스 장애가 동반된 보안 사고가 발생했으며, 일부 보도와 보안 커뮤니티 분석에서는 그 원인 후보 중 하나로 MongoBleed(CVE-2025-14847) 악용 가능성을 언급한 바 있다.
장기간 취약점 미발견 이유
본 취약점이 장기간 드러나지 않은 배경에는, 동일한 입력을 넣어도 노출되는 결과가 매번 달라질 수 있는 특성이 크게 작용한다. 이 유형의 메모리 정보 노출은 힙 레이아웃, 할당/해제 타이밍, 워크로드에 따른 메모리 상태에 영향을 받아 재현이 달라지며, 자동화 테스트나 일반 장애 분석 과정에서 일관된 패턴으로 묶기 어렵다.
운영 측면에서도 관측이 제한적이다. MongoDB의 기본 로그 설정(verbosity=0)은 Informational 로그 중심이며, 오류(Assertion/COMMAND)와 연관된 로그가 시스템 로그에 포함되려면 verbosity가 최소 1(Debug) 이상이어야 한다. 따라서 별도 설정 없이 운영하면 공격 트래픽이 유입되더라도 상세 원인을 식별할 로그가 남지 않아, 현장에서는 단순 연결 종료 또는 일시적 오류처럼 관측될 수 있다.
또한 이 이슈는 인증 이전 경로에서 트리거될 수 있고, 오류 응답이 정상 프로토콜 흐름 안에서 반환될 수 있어 단순 시그니처 기반 탐지나 단순 차단 규칙만으로는 구분이 제한적이라는 점을 언급할 수 있다.
대응 방안
MongoBleed 취약점에 대한 가장 확실한 대응 방법은 패치된 버전으로 즉시 업그레이드하는 것이다. 그러나 다양한 이유로 즉각적인 업데이트가 불가능할 경우, 몇 가지의 임시 완화 조치를 적용할 수 있다. 우선 MongoDB 인스턴스가 인터넷에 직접 노출되지 않도록 방화벽, ACL. VPC 등 네트워크 접근을 최소화한다. 또한 본 취약점은 zlib 기반 OP_COMPRESSED 처리 경로를 악용하므로, zlib 압축 설정을 비활성화하여 zlib 압축 메시지 처리를 차단(허용 목록에서 제거)하도록 한다.

로그 관점에서는 기본 설정(verbosity=0)에서 에러 단서가 충분히 남지 않을 수 있으므로, COMMAND 컴포넌트 verbosity를 1 이상으로 상향해 InvalidBSON 또는 Assertion while parsing command 같은 명령 파싱 실패 단서가 시스템 로그에 포함되도록 가시성을 확보한다.
안랩 대응 현황
안랩 제품군의 진단명 정보는 다음과 같다.
AIPS/HIPS 탐지룰
- MongoDB zlib Decompression Information Disclosure Vulnerability(MongoBleed)-1
결론
MongoBleed(CVE-2025-14847)는 단 한 줄의 길이 처리 오류가 장기간 누적되어 광범위한 위험으로 이어질 수 있음을 보여주는 사례이다. 공개 보도 및 스캔 결과에서는 당시 약 8.7만 대 규모의 인터넷 노출 인스턴스가 언급되기도 했다.
MongoDB 사용자는 패치를 최우선으로 적용하고, 불가피한 경우 네트워크 노출을 차단하며 zlib 비활성화와 로그 가시성 강화를 병행해야 한다. 보안 전문가는 이러한 사례를 연구하여 유사한 취약점을 사전에 발견하고 예방하는 데 활용해야 하며, 소프트웨어 개발자는 보안이 기능보다 우선한다는 원칙을 명심해야 한다. 본 취약점에 대한 상세한 기술 분석은 AhnLab ATIP에서 제공하는 “MongoBleed 취약점 분석 보고서 (CVE-2025-14847) – AhnLab TIP“를 통해 확인 가능하다.
출처
- https://nvd.nist.gov/vuln/detail/CVE-2025-14847
- https://github.com/mongodb/mongo/blob/r8.2.2/src/mongo/transport/message_compressor_manager.h
- https://www.abstract.security/blog/critical-mongodb-vulnerability-cve-2025-14847-mongobleed
- https://www.akamai.com/blog/security-research/cve-2025-14847-all-you-need-to-know-about-mongobleed
- https://censys.com/advisory/cve-2025-14847