highCVE-2026-77406Sep 17, 2026

CVE-2026-77406: amqp091-go Signed-to-Unsigned Integer Overflow in Qos

Shubham Kandhare
Security Engagement Manager, SecureLayer7

Passing a negative prefetch value to the RabbitMQ Go client's Qos method silently wraps it to the maximum unsigned integer, causing the broker to flood the consumer with messages and crash it.

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

The problem

Channel.Qos in channel.go accepts signed int parameters for prefetchCount and prefetchSize, then casts them directly to uint16 and uint32 with no bounds check.

A value of -1 becomes 65535 (prefetchCount) or 4294967295 (prefetchSize) on the wire via Go two's-complement wrapping. Any application that lets untrusted input reach these parameters is exposed to a consumer-side denial of service.

Proof of concept

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

go
// Trigger: call Qos with -1 to wrap prefetchCount to 65535
// and prefetchSize to 4294967295 on the wire.
//
// Vulnerable code path (channel.go, pre-1.13.0):
//   ch.Qos(prefetchCount int, prefetchSize int, global bool)
//   -> basicQos{
//        PrefetchCount: uint16(prefetchCount),  // -1 -> 65535
//        PrefetchSize:  uint32(prefetchSize),   // -1 -> 4294967295
//      }

ch, _ := conn.Channel()
err := ch.Qos(
    -1,    // prefetchCount: wraps to 65535
    -1,    // prefetchSize:  wraps to 4294967295
    false,
)
// Broker now sends the full queue contents with no rate limit.
// Client memory grows unbounded -> OOM crash.

Go's unsigned conversion of a negative signed integer uses two's-complement arithmetic: int(-1) cast to uint16 yields 65535, and to uint32 yields 4294967295. Because no validateQos function existed before 1.13.0, neither value was rejected before being serialised into the AMQP basic.qos wire frame.

The broker faithfully honours the prefetch limit it receives, so it dispatches messages at the maximum possible rate. The root cause is CWE-195 (Signed to Unsigned Conversion Error). The patch in commit 3b879e1 adds an explicit negativity check that returns an error before the cast ever happens.

The fix

Upgrade to amqp091-go v1.13.0. The fix (PR #351, commit 3b879e1d) adds a validateQos guard that returns an error immediately when prefetchCount or prefetchSize is negative, preventing the unsafe cast entirely.

Reported by suchitd.

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

Related research