CVE-2026-73548: Envoy: Cross-user response poisoning via a generic (non-WebSocket) HTTP upgrade on Envoy's shared backend pool
Envoy is an open source edge and service proxy designed for cloud-native applications. Prior to 1.36.10, 1.37.6, 1.38.4, and 1.39.1, Envoy forwards data for a configured non-WebSocket HTTP upgrade before the upstream accepts the upgrade. An unauthenticated HTTP/2 client can place a complete HTTP/1.1 request in extended CONNECT data; Envoy downgrades the request, writes the data unframed to a keep-alive HTTP/1.1 upstream, and returns the socket to the shared pool while the smuggled response remains queued. A different downstream client can then receive the attacker's response. The relevant scope boundary is that webSocket upgrades, plain CONNECT, disabled backend keep-alive, per-downstream pools, and maxrequestsperconnection set to 1 are not affected by the demonstrated path. This issue is fixed in versions 1.36.10, 1.37.6, 1.38.4, and 1.39.1.
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
Envoyto a version that resolves this vulnerability.Fixed in 1.36.10 - Upgrade
Upgrade
Envoyto a version that resolves this vulnerability.Fixed in 1.37.6 - Upgrade
Upgrade
Envoyto a version that resolves this vulnerability.Fixed in 1.38.4 - Upgrade
Upgrade
Envoyto a version that resolves this vulnerability.Fixed in 1.39.1
Event History
Frequently Asked Questions
Which deployments are exposed to the demonstrated attack path?
Deployments using a configured non-WebSocket HTTP upgrade with shared, keep-alive HTTP/1.1 upstream connections are exposed. The attacker can be an unauthenticated HTTP/2 client.
What does an attacker need to do to exploit this issue?
The attacker sends extended CONNECT data containing a complete HTTP/1.1 request. Envoy can downgrade and send that data unframed to the upstream before the upstream accepts the upgrade, leaving the smuggled response queued for another client.
Which configurations are outside the demonstrated affected scope?
WebSocket upgrades and plain CONNECT are not affected by the demonstrated path. Disabling backend keep-alive, using per-downstream connection pools, or setting max_requests_per_connection to 1 also prevents that path.
What can be done if upgrading is not immediately possible?
Disable backend keep-alive, use per-downstream pools, or set max_requests_per_connection to 1 to avoid the demonstrated shared-connection path. The permanent fix is to upgrade to 1.36.10, 1.37.6, 1.38.4, or 1.39.1, as applicable.