highCVE-2026-77412Sep 17, 2026

CVE-2026-77412: amqp091-go Denial of Service via Negative Byte-Array Length

Rohit Hatagale
AI Security Researcher, SecureLayer7

A malicious RabbitMQ broker can crash any connected Go client instantly by sending a single malformed frame that tricks the client into allocating a slice of negative length.

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

The problem

The readField function in read.go parses byte-array fields (type tag 'x') by reading a 32-bit big-endian integer into a signed int32, then passing that value directly to make() for slice allocation.

A broker-controlled value of 0xFFFFFFFF becomes -1 after the signed reinterpretation. Go's runtime panics with 'len out of range' on a negative make() argument. Because the reader goroutine has no recover() wrapper, the panic propagates to the root and terminates the entire client process.

Proof of concept

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

bash
# Minimal AMQP frame bytes that trigger the panic.
# Can appear in connection.start server-properties or message header table.
#
# Field table entry layout:
#   1 byte  field name length     = 0x01
#   1 byte  field name            = 0x78  ('x' as field name, arbitrary)
#   1 byte  field value type tag  = 0x78  ('x' = byte-array)
#   4 bytes field value length    = 0xFF 0xFF 0xFF 0xFF  (0xFFFFFFFF => int32(-1))
#
# Hex bytes to inject inside a valid AMQP table payload:
01 78 78 FF FF FF FF

# In Go terms, the server sends:
# binary.BigEndian.PutUint32(buf, 0xFFFFFFFF)
# which readField decodes as int32(-1), then calls make([]byte, -1) => panic

The root cause is CWE-681: the length is transmitted as an unsigned 32-bit wire value but received into a signed int32. Any wire value >= 0x80000000 produces a negative Go integer.

Go's built-in make() panics immediately on a negative length argument. There is no error path, only a hard crash.

The fix in PR #344 (commit 669b42bf) reads the length into a uint32 first, then validates it is within a sane range before converting to int for make(). Values that would have been negative as int32 are now rejected with a proper error, keeping the reader goroutine alive.

The fix

Upgrade github.com/rabbitmq/amqp091-go to v1.13.0. The patch (PR #344) changes the length variable from int32 to uint32 and adds a bounds check before allocation, returning a parse error instead of panicking. No workaround exists for older versions; only a broker you control and trust can prevent exploitation.

Reported by MirahImage.

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

Related research