Update module github.com/moby/spdystream to v0.5.1 [SECURITY] (release-0.36)#540
Conversation
Signed-off-by: redhat-renovate-bot <redhat-internal-renovate@redhat.com>
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: redhat-renovate-bot The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
There was a problem hiding this comment.
Code Review
This pull request updates the github.com/moby/spdystream dependency to v0.5.1 and introduces configurable frame parsing limits to mitigate potential resource exhaustion. It also improves timer management during connection shutdown and wait operations. Feedback on these changes highlights a potential Denial of Service (DoS) vulnerability in read.go where io.CopyN is used to drain connections on oversized frames, which could block indefinitely. Additionally, a redundant data length check was identified in write.go that can be safely removed to simplify the code.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| if length > maxControlFramePayload { | ||
| if _, err := io.CopyN(ioutil.Discard, f.r, int64(length)); err != nil { | ||
| return nil, err | ||
| } | ||
| return nil, &Error{InvalidControlFrame, 0} | ||
| } |
There was a problem hiding this comment.
Calling io.CopyN to drain the connection when the frame exceeds maxControlFramePayload introduces a potential Denial of Service (DoS) vulnerability. If an attacker sends a control frame header with a very large length (up to 16MB) and then stops sending data, io.CopyN will block indefinitely waiting for the remaining bytes. Since spdystream closes the connection immediately upon receiving an InvalidControlFrame error anyway, there is no need to drain the connection. Returning the error immediately allows the connection to be closed promptly, releasing the blocked goroutine and connection resources.
if length > maxControlFramePayload {
return nil, &Error{InvalidControlFrame, 0}
}| dLen := len(frame.Data) | ||
| if dLen > MaxDataLength { | ||
| return &Error{InvalidDataFrame, frame.StreamId} | ||
| } | ||
| flagsAndLength := uint32(frame.Flags)<<24 | uint32(dLen) |
There was a problem hiding this comment.
Since len(frame.Data) > MaxDataLength is already checked at the very beginning of the function (line 335), this second check is redundant and can be removed to simplify the code.
| dLen := len(frame.Data) | |
| if dLen > MaxDataLength { | |
| return &Error{InvalidDataFrame, frame.StreamId} | |
| } | |
| flagsAndLength := uint32(frame.Flags)<<24 | uint32(dLen) | |
| flagsAndLength := uint32(frame.Flags)<<24 | uint32(len(frame.Data)) |
This PR contains the following updates:
v0.4.0→v0.5.1SpdyStream: DOS on CRI
CVE-2026-35469 / GHSA-pc3f-x583-g7j2 / GO-2026-4958
More information
Details
The SPDY/3 frame parser in spdystream does not validate
attacker-controlled counts and lengths before allocating memory. A
remote peer that can send SPDY frames to a service using spdystream can
cause the process to allocate gigabytes of memory with a small number of
malformed control frames, leading to an out-of-memory crash.
Three allocation paths in the receive side are affected:
numSettingsfrom the payload and allocates a slice of that sizewithout checking it against the declared frame length. An attacker
can set
numSettingsto a value far exceeding the actual payload,triggering a large allocation before any setting data is read.
parseHeaderValueBlockreads a 32-bitnumHeadersfrom the decompressed header block and allocates anhttp.Headermap of that size with no upper bound.read as 32-bit integers and used directly as allocation sizes with
no validation.
Because SPDY header blocks are zlib-compressed, a small on-the-wire
payload can decompress into attacker-controlled bytes that the parser
interprets as 32-bit counts and lengths. A single crafted frame is
enough to exhaust process memory.
Impact
Any program that accepts SPDY connections using spdystream -- directly
or through a dependent library -- is affected. A remote peer that can
send SPDY frames to the service can crash the process with a single
crafted SPDY control frame, causing denial of service.
Affected versions
github.com/moby/spdystream<= v0.5.0Fix
v0.5.1 addresses the receive-side allocation bugs and adds related
hardening:
Core fixes:
checks that
numSettingsis consistent with the declared framelength (
numSettings <= (length-4)/8) before allocating.parseHeaderValueBlockenforces a maximumnumber of headers per frame (default: 1000).
lengths are checked against a per-field size limit (default: 1 MiB)
before allocation.
now closes the underlying
net.Connwhen it encounters anInvalidControlFrameerror, preventing further exploitation on thesame connection.
Additional hardening:
that payloads fit within the 24-bit length field, preventing the
library from producing invalid frames.
Configurable limits:
NewConnectionWithOptionsorthe lower-level
spdy.NewFramerWithOptionswith functional options:WithMaxControlFramePayloadSize,WithMaxHeaderFieldSize, andWithMaxHeaderCount.Severity
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:NReferences
This data is provided by OSV and the GitHub Advisory Database (CC-BY 4.0).
Uncontrolled resource consumption when parsing SPDY frames in github.com/moby/spdystream
CVE-2026-35469 / GHSA-pc3f-x583-g7j2 / GO-2026-4958
More information
Details
The SPDY/3 frame parser in spdystream does not validate attacker-controlled counts and lengths before allocating memory. A remote peer that can send SPDY frames to a service using spdystream can cause the process to allocate gigabytes of memory with a small number of malformed control frames, leading to an out-of-memory crash.
Three allocation paths in the receive side are affected:
Because SPDY header blocks are zlib-compressed, a small on-the-wire payload can decompress into attacker-controlled bytes that the parser interprets as 32-bit counts and lengths. A single crafted frame is enough to exhaust process memory.
Severity
Unknown
References
This data is provided by OSV and the Go Vulnerability Database (CC-BY 4.0).
Release Notes
moby/spdystream (github.com/moby/spdystream)
v0.5.1Compare Source
What's Changed
Security
Fix memory amplification in SPDY frame parsing leads to denial of service (CVE-2026-35469 / GHSA-pc3f-x583-g7j2)
Changes
Full Changelog: moby/spdystream@v0.5.0...v0.5.1
v0.5.0: [v0.5.0] Avoid leaking timeout timer channels and update github actionsCompare Source
What's Changed
Full Changelog: moby/spdystream@v0.4.0...v0.5.0
Configuration
📅 Schedule: (UTC)
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR has been generated by Mend Renovate.