Описание
Stream Management Super-Stream Binding Keys Allocation Allows Low-Privilege Node Denial of Service
Summary
RabbitMQ 4.3.1 with rabbitmq_stream_management enabled accepts PUT /api/stream/super-streams/{vhost}/{name} requests from an authenticated management user that can access the target vhost. When the request body contains the binding-keys field, the handler parses the attacker-controlled comma-separated string and builds the full stream-name list before checking whether the user has permission to configure the resulting streams.
A low-privileged management user with vhost access but no configure, write, or read permission can therefore force large transient allocations before the resource permission check. In a 768 MB memory-limited container, one HTTP PUT with about 4.5 MB of JSON body killed the RabbitMQ container with Docker state exited true 137.
This is an authenticated low-privilege availability issue. It is not RCE, not unauthenticated, and not a universal crash on hosts without a hard memory limit. The strongest impact is in Kubernetes, Docker, systemd, or other deployments where RabbitMQ runs under a hard memory cap.
Affected Version
Tested affected version: RabbitMQ 4.3.1.
Tested image: rabbitmq:4.3.1-management.
Tested source tag: v4.3.1.
Tested source commit: 49decca35e59d2cb774e5abd76412cee721308a5.
Required plugins:
Severity
Suggested severity: High.
The issue allows an authenticated management user with vhost membership, but no resource permissions, to kill a memory-limited RabbitMQ node with a single request. The impact is complete node availability loss in the affected deployment model. The issue should be scored as an availability bug and should account for the deployment condition that a hard memory limit is required for the reliable node kill demonstrated here.
Prerequisites
The attacker needs:
- Network access to the RabbitMQ Management HTTP API.
- Valid credentials for a user with the
managementtag. - Access to the target vhost.
The attacker does not need configure, write, or read permission on the vhost resources.
Verified exploitable user:
Negative controls:
- Unauthenticated requests are rejected before body decoding.
- A management user without access to the vhost is rejected before the expensive allocation path.
Root Cause
The affected handler is:
The relevant flow is:
The resource permission check is later:
In the tested source checkout, binding_keys/1 and streams_from_binding_keys/2 are reached before rabbit_stream_utils:check_super_stream_management_permitted/4. This means the code builds attacker-sized lists and binaries before the operation is rejected for missing resource permissions.
Verification
Lab:
Setup commands:
Safe low-count verification:
Observed result:
This confirms that the low-privileged management user reaches the endpoint and is rejected at the later resource permission check.
Destructive OOM verification:
Observed result from repeated lab runs:
Docker state after the destructive run:
The request body is below the observed default management body limit of 10000000 bytes.
Threshold probing in the same 768 MB lab showed safe responses through about 350,000 binding keys and OOM kill at about 375,000 binding keys. The exact threshold depends on memory limit, current node memory use, enabled plugins, and host/container configuration.
Impact
An authenticated low-privileged management user can kill a memory-limited RabbitMQ node with one HTTP request. The user does not need configure, write, or read permissions on the vhost resources. The failure is a hard process kill by the cgroup OOM killer, so all connections and vhosts on the node are unavailable until the container or service is restarted.
On a host or container without a hard memory limit, the same request causes large memory growth but may not immediately kill the broker. The reliable node-kill impact is therefore deployment dependent.
Proof of Concept
The attached poc_stream_superstream_oom.py defaults to a safe low-count run. It prints broker ping, memory use, HTTP status, and Docker state.
Safe command:
Destructive command:
Do not run the destructive mode against a production broker.
Remediation
Recommended fixes:
- Move the resource permission check before expanding
binding-keysinto a full stream list. - Enforce a maximum
binding-keysbyte length before splitting. - Enforce a maximum binding key count before building derived stream names.
- Avoid converting large untrusted binaries through
binary_to_listandlist_to_binarybefore authorization. - Return a cheap rejection for users that cannot configure the target super-stream before allocating per-binding-key data.
Пакеты
rabbitmq
>= 4.3.0, < 4.3.3
4.3.3
rabbitmq
>= 4.2.0, < 4.2.9
4.2.9
rabbitmq
>= 4.1.0, < 4.1.11
4.1.11