CVE-2026-35469: SpdyStream: DOS on CRI
spdystream is a Go library for multiplexing streams over SPDY connections. In versions 0.5.0 and below, the SPDY/3 frame parser does not validate attacker-controlled counts and lengths before allocating memory. Three allocation paths are affected: the SETTINGS frame entry count, the header count in parseHeaderValueBlock, and individual header field sizes — all read as 32-bit integers and used directly as allocation sizes with no bounds checking. Because SPDY header blocks are zlib-compressed, a small on-the-wire payload can decompress into large attacker-controlled values. A remote peer that can send SPDY frames to a service using spdystream can exhaust process memory and cause an out-of-memory crash with a single crafted control frame. This issue has been fixed in version 0.5.1.
Other sources
Summary: Possible DOS in SPDY streaming code, used for attach, exec and port forwarding.
Requirements To Exploit: Access to the kubelet's endpoint (granted through nodes/proxy) or access to any of portforward, exec, or attach to pods. These all can be represented by the cluster roles
pods/portforward (create)
pods/exec (create)
pods/attach (create)
nodes/proxy (get/create)
Component Affected: Kubelet, CRI-O, kube-apiserver
Version Affected: Openshift 4.21.4 and below
Patch Available: yes
Version Fixed: none yet
Cvss: (Based on [https://nvd.nist.gov/vuln-metrics/cvss/v3-calculator]). Please note that only the Base Score Metrics are required by the incident response team.
Impact: Based on the https://access.redhat.com/security/updates/classification , what do you think would be the impact and why? This helps a lot the analyst to understand why such a report must be or not considered Moderate/Important or even Critical.
Steps To Reproduce: apply:
— apiVersion: v1 kind: ServiceAccount metadata: name: poc-sa-portforward namespace: default — apiVersion: [rbac.authorization.k8s.io/v1:(http://rbac.authorization.k8s.io/v1)(http://rbac.authorization.k8s.io/v1)] kind: Role metadata: name: poc-role-portforward namespace: default rules:
apiGroups: [""] resources: ["pods/portforward"] verbs: ["create"] — apiVersion: [rbac.authorization.k8s.io/v1:(http://rbac.authorization.k8s.io/v1)(http://rbac.authorization.k8s.io/v1)] kind: RoleBinding metadata: name: poc-rb-portforward namespace: default subjects:
kind: ServiceAccount name: poc-sa-portforward namespace: default roleRef: kind: Role name: poc-role-portforward apiGroup: rbac.authorization.k8s.io — apiVersion: v1 kind: Pod metadata: name: poc-target namespace: default spec: containers:
name: nginx image: nginx:alpine
set env:
export APISERVER=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}' | sed 's|https://||')
export TOKEN=$(kubectl create token poc-sa-portforward)
export POD=poc-target
run attached pocportforward.py
Mitigation: disable the above cluster roles from untrusted users.
Embargo Reason: Coordination with three upstream communities: containerd, CRI-O, kubernetes
Original Report: https://github.com/moby/spdystream/security/advisories/GHSA-pc3f-x583-g7j2
— Red Hat
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: 1. SETTINGS entry count -- The SETTINGS frame reader reads a 32-bit numSettings from the payload and allocates a slice of that size without checking it against the declared frame length. An attacker can set numSettings to a value far exceeding the actual payload, triggering a large allocation before any setting data is read. 2. Header count -- parseHeaderValueBlock reads a 32-bit numHeaders from the decompressed header block and allocates an http.Header map of that size with no upper bound. 3. Header field size -- Individual header name and value lengths are 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.0 Fix v0.5.1 addresses the receive-side allocation bugs and adds related hardening: Core fixes: - SETTINGS entry-count validation -- The SETTINGS frame reader now checks that numSettings is consistent with the declared frame length (numSettings <= (length-4)/8) before allocating. - Header count limit -- parseHeaderValueBlock enforces a maximum number of headers per frame (default: 1000). - Header field size limit -- Individual header name and value lengths are checked against a per-field size limit (default: 1 MiB) before allocation. - Connection closure on protocol error -- The connection read loop now closes the underlying net.Conn when it encounters an InvalidControlFrame error, preventing further exploitation on the same connection. Additional hardening: - Write-side bounds checks -- All frame write methods now verify that payloads fit within the 24-bit length field, preventing the library from producing invalid frames. Configurable limits: - Callers can adjust the defaults using NewConnectionWithOptions or the lower-level spdy.NewFramerWithOptions with functional options: WithMaxControlFramePayloadSize, WithMaxHeaderFieldSize, and WithMaxHeaderCount.
— GitHub
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
go/github.com/moby/spdystreamto a version that resolves this vulnerability.Fixed in 0.5.1 - Upgrade
Upgrade
github.com/moby/spdystreamto a version that resolves this vulnerability.Fixed in 0.5.1 - Configuration
When creating the SPDY framer, use functional options to cap control-frame payloads (e.g., WithMaxControlFramePayloadSize) so attackers cannot trigger large allocations via SETTINGS/control frames.
spdy.NewFramerWithOptions (github.com/moby/spdystream) WithMaxControlFramePayloadSize = set a maximum control frame payload size (default described as existing) - Configuration
Use the functional option WithMaxHeaderFieldSize to enforce a per-field size limit (default stated as 1 MiB) to prevent oversized header name/value allocations.
spdy.NewFramerWithOptions (github.com/moby/spdystream) WithMaxHeaderFieldSize = set a per-header field size limit (default: 1 MiB as stated) - Configuration
Use the functional option WithMaxHeaderCount to enforce the maximum number of headers per frame (default stated as 1000) to prevent attacker-controlled header-count allocations.
spdy.NewFramerWithOptions (github.com/moby/spdystream) WithMaxHeaderCount = set a maximum number of headers per frame (default: 1000 as stated) - Configuration
Disable the cluster roles that allow access to kubelet endpoints via nodes/proxy and access to pods/portforward, pods/exec, and pods/attach from untrusted users (the text explicitly says to disable those cluster roles from untrusted users).
Kubernetes RBAC disable cluster roles from untrusted users (RBAC rules/rolebindings) = disallow these roles for untrusted users - Compensating control
If available for your spdystream integration, ensure the connection read loop closes the underlying net.Conn upon protocol errors (the material states the parser now closes the connection on protocol error) to prevent continued exploitation attempts on the same connection.
Event History
Frequently Asked Questions
What is the severity of CVE-2026-35469?
CVE-2026-35469 has a high severity due to its potential for denial of service attacks.
How do I fix CVE-2026-35469?
To fix CVE-2026-35469, upgrade the affected library to version 0.5.1 or later.
What is the impact of CVE-2026-35469?
CVE-2026-35469 can lead to denial of service by exploiting improper memory allocation.
Which versions of spdystream are affected by CVE-2026-35469?
Versions 0.5.0 and below of the spdystream library are affected by CVE-2026-35469.
What software uses spdystream and is affected by CVE-2026-35469?
The azl3 containerd2 product by Microsoft is one of the software that uses spdystream and is affected by CVE-2026-35469.