Public mode

No access to your tenant or devices. Every item links to its source. What this means

Some sources, documents or advisories need attention: 275/275 feeds/APIs · 469/469 docs · 8/9 advisories · checked 13:19 UTC Customize Public modeDiscuss ChangeIntel on Discord

amqp091-go: Pre-negotiation frame limit is not enforced to 4KB

Collected exploitation and prediction evidence

Risk source coverage

CISA KEV is observed exploitation evidence. FIRST EPSS is a dated prediction of exploitation in the next 30 days. Missing scores are unknown. This collector requests predictions only for explicit CVE aliases in the public NuGet archive; Microsoft release views retain their existing prediction scope.

No collected risk observation for these identifiers. This does not establish absence of exploitation or a zero probability.

cve-program · CVE-2026-107386

Published

amqp091-go is a Go AMQP 0.9.1 client. From 1.13.0 until 1.14.0, the frame-size mitigation from the prior allocation advisory can be bypassed before connection.tune completes because Connection.maxFrameSize uses zero for both the not-yet-negotiated and negotiated-unlimited states. A malicious or compromised AMQP peer can send a short body-frame header with a large declared payload length, causing ReadFrame and the body-frame parser to allocate attacker-selected memory before the payload is received or the frame's protocol state is rejected. The condition is reachable through public Open even when Config.FrameSize is set to the protocol minimum and can cause severe memory pressure, out-of-memory termination, or loss of the client process before authentication completes. This issue is fixed in version 1.14.0.

Source published
8 Oct 2026 18:54:12 UTC
Source modified
9 Oct 2026 15:14:35 UTC
Observed here
23 Oct 2026 15:48:27 UTC
Source terms
CVE Program Terms of Use

Original source record · Cite this exact observation · Complete original publisher JSON

This view projects the publisher's source fields for reading; the original JSON retains additional fields and CVE enrichment containers. Attribution: cve-program · CVE Program Terms of Use. Source text is retained; field grouping and change labels are provided by ChangeIntel.

CVSS 4.0 · 6.3 CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N

euvd · EUVD-2026-95161

Published

amqp091-go is a Go AMQP 0.9.1 client. From 1.13.0 until 1.14.0, the frame-size mitigation from the prior allocation advisory can be bypassed before connection.tune completes because Connection.maxFrameSize uses zero for both the not-yet-negotiated and negotiated-unlimited states. A malicious or compromised AMQP peer can send a short body-frame header with a large declared payload length, causing ReadFrame and the body-frame parser to allocate attacker-selected memory before the payload is received or the frame's protocol state is rejected. The condition is reachable through public Open even when Config.FrameSize is set to the protocol minimum and can cause severe memory pressure, out-of-memory termination, or loss of the client process before authentication completes. This issue is fixed in version 1.14.0.

EUVD source date text has no stated timezone and is retained without inventing a UTC instant. Related bulletin membership is not an alias, common cause or applicability claim. A missing vector with a zero score is treated as unrated. Complete vendor/product and underlying source evidence remains in the original JSON.

Original publisher date fields

datePublished: Oct 8, 2026, 6:54:12 PM

dateUpdated: Oct 9, 2026, 3:14:35 PM

1 related source bulletins · separate from aliases

RHSA-2026:80217: Red Hat Security Advisory: Red Hat Hardened Images RPMs Security Update

CVE-2026-79921 · CVE-2026-107386

Source published
Oct 8, 2026, 6:54:12 PM (timezone not stated)
Source modified
Oct 9, 2026, 3:14:35 PM (timezone not stated)
Observed here
7 Nov 2026 04:31:20 UTC
Source terms
ENISA EUVD · source terms and attribution apply

Original source record · Cite this exact observation · Complete original publisher JSON

This view projects the publisher's source fields for reading; the original JSON retains additional fields and CVE enrichment containers. Attribution: euvd · ENISA EUVD · source terms and attribution apply. Source text is retained; field grouping and change labels are provided by ChangeIntel.

EUVD CVSS 4.0 · 6.3 CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N

nvd · CVE-2026-107386

Published

amqp091-go is a Go AMQP 0.9.1 client. From 1.13.0 until 1.14.0, the frame-size mitigation from the prior allocation advisory can be bypassed before connection.tune completes because Connection.maxFrameSize uses zero for both the not-yet-negotiated and negotiated-unlimited states. A malicious or compromised AMQP peer can send a short body-frame header with a large declared payload length, causing ReadFrame and the body-frame parser to allocate attacker-selected memory before the payload is received or the frame's protocol state is rejected. The condition is reachable through public Open even when Config.FrameSize is set to the protocol minimum and can cause severe memory pressure, out-of-memory termination, or loss of the client process before authentication completes. This issue is fixed in version 1.14.0.

NVD analysis and CPE criteria are source context, not proof that a package or your environment is affected. Complete affected data, logical configurations and SSVC are retained in the original JSON.

Source analysis status: Deferred

Weakness classifications: CWE-770

Original publisher date fields

published: 2026-10-08T19:17:01.347

lastModified: 2026-10-09T16:17:22.590

Source published
8 Oct 2026 19:17:01 UTC
Source modified
9 Oct 2026 16:17:22 UTC
Observed here
25 Oct 2026 05:17:13 UTC
Source terms
NIST NVD usage terms; underlying source attribution retained

Original source record · Cite this exact observation · Complete original publisher JSON

This view projects the publisher's source fields for reading; the original JSON retains additional fields and CVE enrichment containers. Attribution: nvd · NIST NVD usage terms; underlying source attribution retained. Source text is retained; field grouping and change labels are provided by ChangeIntel.

CVSS 4.0 · [email protected] · Secondary · 6.3 CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

osv · GHSA-w6r9-248c-frg8

Published

## Summary The frame-size mitigation released in `amqp091-go` v1.13.0 can be bypassed before `connection.tune` completes. A malicious or compromised AMQP peer can send only a seven-byte body-frame header containing a large attacker-controlled `uint32` payload length. The client allocates a slice of that declared length before it verifies that the payload exists or rejects the frame for its invalid protocol state. The bypass occurs because `Connection.maxFrameSize` starts at zero. The reader interprets zero as both “negotiated unlimited” and “not negotiated yet,” and skips the pre-allocation size check in either case. `Open` starts the reader goroutine before negotiation and does not store a limit until after it receives `connection.tune`. This remains reachable even if the caller explicitly uses `Config{FrameSize: frameMinSize}`. A malicious broker can therefore cause excessive memory allocation, potentially terminating the Go client process through memory exhaustion, before authentication and connection setup complete. ## Relationship to the existing advisory [GHSA-r9c8-gcjp-xfwh](https://github.com/rabbitmq/amqp091-go/security/advisories/GHSA-r9c8-gcjp-xfwh) describes attacker-controlled, unbounded allocation by a malicious broker and identifies v1.13.0 as the patched version. [Pull request 369](https://github.com/rabbitmq/amqp091-go/pull/369) added a frame-size check before parser allocation, but the check is active only when the stored maximum is nonzero. The v1.13.0 source still: 1. starts the reader before protocol negotiation; 2. skips the bound while `maxFrameSize == 0`; 3. allocates the body using the peer-declared size; and 4. stores the negotiated maximum only after `connection.tune`. This appears to be an incomplete-fix or state-boundary bypass of the existing advisory rather than an unrelated allocation issue. ## Affected source and root cause The issue was reproduced at commit [`9313fd9ea47bdb4e8f7f5db9bef94d5534d0bdde`](https://github.com/rabbitmq/amqp091-go/commit/9313fd9ea47bdb4e8f7f5db9bef94d5534d0bdde), dated 2026-07-30. The same relevant control flow is in the v1.13.0 tag. The vulnerable sequence is: 1. [`Open` starts `c.reader(conn)` before calling `c.open(config)`](https://github.com/rabbitmq/amqp091-go/blob/9313fd9ea47bdb4e8f7f5db9bef94d5534d0bdde/connection.go#L373-L392). 2. [The reader receives a pointer to the initially zero-valued `c.maxFrameSize`](https://github.com/rabbitmq/amqp091-go/blob/9313fd9ea47bdb4e8f7f5db9bef94d5534d0bdde/connection.go#L971-L979). 3. [`ReadFrame` decodes the peer-controlled `uint32` size but rejects it only when `max > 0`](https://github.com/rabbitmq/amqp091-go/blob/9313fd9ea47bdb4e8f7f5db9bef94d5534d0bdde/read.go#L46-L79). 4. [`parseBodyFrame` executes `make([]byte, size)` before `io.ReadFull`](https://github.com/rabbitmq/amqp091-go/blob/9313fd9ea47bdb4e8f7f5db9bef94d5534d0bdde/read.go#L459-L466). 5. [`maxFrameSize` is first stored after processing `connection.tune`](https://github.com/rabbitmq/amqp091-go/blob/9313fd9ea47bdb4e8f7f5db9bef94d5534d0bdde/connection.go#L1297-L1305). The source comments and regression tests explicitly combine “negotiated unlimited” with “not yet negotiated” as the same zero state. Those states need different security behavior. ## Safe reproduction This reproducer does not start RabbitMQ, contact any hosted service, send a large payload, or attempt to crash the process. It declares a 2 MiB body and observes the size of the slice passed to the transport's payload `Read`. Receiving a 2 MiB destination slice proves that the allocation occurred; the test then releases the blocked read and exits. 1. Check out v1.13.0. 2. Save the following as `pre_negotiation_frame_limit_test.go` in the repository root. 3. Run `go test -run '^TestPreNegotiationFrameLimitBypass$' -count=1 -v .`. ```go package amqp091 import ( "encoding/binary" "io" "sync" "testing" "time" ) const declaredBodySize = 2 << 20 type stagedFrameConn struct { mu sync.Mutex header []byte headerRead bool bodyRead chan int bodyOnce sync.Once release chan struct{} releaseOnce sync.Once } func newStagedFrameConn() *stagedFrameConn { header := make([]byte, 7) header[0] = frameBody binary.BigEndian.PutUint16(header[1:3], 1) binary.BigEndian.PutUint32(header[3:7], declaredBodySize) return &stagedFrameConn{ header: header, bodyRead: make(chan int, 1), release: make(chan struct{}), } } func (c *stagedFrameConn) Read(p []byte) (int, error) { c.mu.Lock() if !c.headerRead { c.headerRead = true n := copy(p, c.header) c.mu.Unlock() return n, nil } c.mu.Unlock() c.bodyOnce.Do(func() { c.bodyRead <- len(p) }) <-c.release return 0, io.EOF } func (c *stagedFrameConn) Write(p []byte) (int, error) { return len(p), nil } func (c *stagedFrameConn) Close() error { c.releaseOnce.Do(func() { close(c.release) }) return nil } func TestPreNegotiationFrameLimitBypass(t *testing.T) { conn := newStagedFrameConn() openDone := make(chan error, 1) go func() { _, err := Open(conn, Config{FrameSize: frameMinSize}) openDone <- err }() select { case got := <-conn.bodyRead: if got != declaredBodySize { t.Fatalf("payload Read received a %d-byte slice; want %d", got, declaredBodySize) } case <-time.After(5 * time.Second): t.Fatal("payload Read was not reached") } _ = conn.Close() select { case <-openDone: case <-time.After(5 * time.Second): t.Fatal("Open did not exit after the test connection closed") } } ``` ### Expected secure behavior The pre-negotiation reader rejects the oversized declared frame before allocating its payload buffer. The transport should never receive a payload `Read` with a 2 MiB destination slice. ### Actual behavior The test passes because the transport receives a payload `Read` whose destination slice is exactly 2 MiB, despite the caller setting `Config.FrameSize` to `frameMinSize`. This slice was created by `make([]byte, size)` using the untrusted frame header. ## Additional local validation A five-test differential harness was run against the exact tested commit. All tests passed: ```text === RUN TestCounterfactualZeroFrameLimitAllocatesBeforePayloadRead --- PASS: TestCounterfactualZeroFrameLimitAllocatesBeforePayloadRead === RUN TestCounterfactualNegotiatedLimitRejectsBeforePayloadAllocation --- PASS: TestCounterfactualNegotiatedLimitRejectsBeforePayloadAllocation === RUN TestCounterfactualZeroLimitAllowsSmallFrameControl --- PASS: TestCounterfactualZeroLimitAllowsSmallFrameControl === RUN TestCounterfactualNegotiatedLimitAllowsSmallFrameControl --- PASS: TestCounterfactualNegotiatedLimitAllowsSmallFrameControl === RUN TestCounterfactualPublicOpenReachesZeroLimitAllocation --- PASS: TestCounterfactualPublicOpenReachesZeroLimitAllocation PASS ok github.com/rabbitmq/amqp091-go 0.907s ``` The controls establish that: - the zero pre-negotiation state reaches attacker-sized allocation; - a `frameMinSize` bound rejects the same declaration before allocation; - both states continue to accept a valid small frame; and - the vulnerable state is reachable through public `Open`, not only through an internal helper. ## Impact The frame body length is a network-controlled 32-bit unsigned integer, so one seven-byte frame header can request an allocation approaching 4 GiB on a 64-bit client. The attacker does not need to transmit the declared body before allocation occurs. On memory-constrained clients or containers, this can cause severe memory pressure, an out-of-memory condition, or process termination. The required attacker position is a malicious or compromised broker, or an equivalent peer able to provide the AMQP transport during connection establishment. No application credentials, user interaction, confidentiality impact, or integrity impact is required or claimed. The primary impact is availability of the client process and potentially dependent services. ## Protocol relevance The [AMQP 0-9-1 reference](https://github.com/rabbitmq/amqp-0.9.1-spec/blob/main/docs/amqp-0-9-1-reference.md#L395-L398) requires peers to accept frames up to the 4096-byte `frame-min-size` before `frame-max` is negotiated. It does not require accepting arbitrarily large pre-negotiation frames. A provisional 4096-byte receive limit is therefore compatible with the stated pre-negotiation requirement. ## Suggested remediation Represent these states separately: - pre-negotiation, with a provisional `frameMinSize` receive bound; - negotiated with a finite `frame_max`; and - explicitly negotiated unlimited, if that behavior remains supported. Initialize the provisional bound before the reader goroutine starts, then replace it with the negotiated result after `connection.tune`. Reject any declared payload that would make the total frame exceed the active limit before calling a frame parser or allocating a payload buffer. A protocol-state check that rejects body frames before connection setup completes would add defense in depth. Please add a regression through public `Open` that sends an oversized body-frame header before `connection.tune` and verifies rejection before payload allocation, while retaining small valid-frame controls.

Source published
8 Oct 2026 19:40:19 UTC
Source modified
19 Oct 2026 21:41:15 UTC
Observed here
24 Oct 2026 13:19:41 UTC
Source terms
GitHub Advisory Database · CC-BY-4.0

Original source record · Cite this exact observation · Complete original publisher JSON

This view projects the publisher's source fields for reading; the original JSON retains additional fields and CVE enrichment containers. Attribution: osv · GitHub Advisory Database · CC-BY-4.0. Source text is retained; field grouping and change labels are provided by ChangeIntel.

CVSS_V4 · CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N

Publisher rating · MODERATE

osv · GO-2026-6700

Published

Pre-negotiation frame limit is not enforced to 4KB in github.com/rabbitmq/amqp091-go

Source published
19 Oct 2026 21:08:21 UTC
Source modified
19 Oct 2026 21:31:49 UTC
Observed here
24 Oct 2026 13:19:41 UTC
Source terms
OSV · upstream source license applies

Original source record · Cite this exact observation · Complete original publisher JSON

This view projects the publisher's source fields for reading; the original JSON retains additional fields and CVE enrichment containers. Attribution: osv · OSV · upstream source license applies. Source text is retained; field grouping and change labels are provided by ChangeIntel.

ChangeIntel

An IT change radar: releases, security, known issues, retirements, documentation changes, and service status from public sources. Every item links to supporting evidence; dates and statuses can change after they are read.

Sources read 8 Nov 13:19 UTC · 275 of 275 readable · 273 fully read · documentation 469/469 current