Описание
RabbitMQ AMQP 1.0 parser: amplification memory-exhaustion DoS via zero-width array aggregation
Summary
An amplification memory-exhaustion denial of service exists in RabbitMQ's AMQP 1.0 type parser. Any client that can complete a SASL handshake (by default guest/guest; any valid low-privilege user in a real deployment — with only vhosts access permissions required) can send a single ~30–128 KB frame that the parser expands into multiple gigabytes of heap. A cap limits the size of any one "zero-width" array to 10,000 elements, but there is no aggregate limit on how many such arrays a single frame may contain. The frame is parsed in the connection reader process BEFORE any validation or authorization, and the reader's max_heap_size kill-guard is cleared immediately after authentication — so nothing bounds the allocation. A few tens of KB of traffic trips the node-wide memory alarm (blocking all publishers on the node) and, with a few concurrent frames (~180 KB total), OOM-kills the entire broker. Measured amplification: ~50,000× (30 KB in → ~2.4 GB heap).
Details
Root cause — deps/amqp10_common/src/amqp10_binary_parser.erl:
Where it detonates (before any validation) — deps/rabbit/src/rabbit_amqp_reader.erl:
The parse (and its allocation) runs for every frame body in the reader process; any later rejection by amqp10_framing:decode happens only after the memory has already been consumed.
Why the reader guard does not help post-auth — deps/rabbit/src/rabbit_amqp_reader.erl:
Pre-auth, max_heap_size = 16 MiB (kill=true) limits damage to a single-connection kill. On SASL success the guard is cleared, so nothing bounds the reader process heap thereafter.
Frame-size window: post-open, incoming_max_frame_size = frame_max = 131072 (128 KB), giving ~13,100 arrays/frame ⇒ ~2 GB/frame.
PoC
Attack: a raw-socket AMQP 1.0 client (Python stdlib only, attached as amqp10_bomb.py) that
(1) does SASL PLAIN as guest, (2) sends open, (3) sends one frame containing an outer list32 of N zero-width null arrays — each f0 00000005 00002710 40 (array32, count=10000, elem=null).
Poc Script: amqp10_bomb.py
Measure broker memory in a separate window:
Impact
Type: CWE-770 / CWE-400 — Denial of Service (uncontrolled memory allocation).
- Whole-node crash (OOM) of the broker from a single connection sending tens of KB.
- Node-wide publisher blocking as soon as the memory high-watermark is crossed — degrading availability for ALL tenants/vhosts on the node even without a crash.
- Trivially repeatable; ~50,000× amplification means negligible attacker bandwidth. channel_max / session limits do not help — the allocation is in the connection reader, before session or link handling.
Who is impacted:
Any RabbitMQ deployment with the AMQP 1.0 listener enabled (default on 5672 in 4.x) reachable by any authenticated principal — i.e. effectively all network-exposed brokers.
Пакеты
rabbitmq
>= 4.3.0, < 4.3.4
4.3.4
rabbitmq
>= 4.2.0, < 4.2.10
4.2.10
rabbitmq
>= 4.1.0, < 4.1.15
4.1.15
rabbitmq
>= 4.0.0, < 4.0.24
4.0.24