CVE-2024-32974
Executive Summary
CVE-2024-32974 is a use-after-free vulnerability in Envoy, the cloud-native edge and service proxy, specifically within the QUIC (HTTP/3) stream handling code. The flaw resides in EnvoyQuicServerStream::OnInitialHeadersComplete(), where a race condition allows QUICHE (the QUIC implementation used by Envoy) to continue processing push request headers after StopReading() has been called on the stream. Once StopReading() is invoked, the HCM (HTTP Connection Manager) ActiveStream object may be deallocated, leading to a use-after-free crash when QUICHE subsequently attempts to deliver headers. This vulnerability can be triggered remotely by a malicious client sending specially crafted QUIC push requests, resulting in a denial of service (DoS) condition. No public exploit code or proof-of-concept is available at this time, and the EPSS score is 0.0%, indicating low exploitation likelihood in the wild. However, given Envoy’s widespread use in cloud-native environments, the risk to availability is significant.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
Envoy is distributed as a container image (e.g., envoyproxy/envoy) and via package managers for Linux distributions. Organizations using Envoy as a sidecar proxy in Kubernetes or as an API gateway should verify their version’s QUIC support. The vulnerability affects the QUIC/HTTP/3 code path, which may be disabled by default in some configurations. No malicious packages have been identified in the supply chain related to this CVE.
CVSS Breakdown & Threat Level
- CVSS Score: 5.9 (Medium)
- Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L
- Attack Vector: Network
- Attack Complexity: Low
- Privileges Required: None
- User Interaction: None
- Scope: Unchanged
- Confidentiality Impact: None
- Integrity Impact: None
- Availability Impact: Low
The vulnerability is remotely exploitable without authentication, but only results in a crash (denial of service) with no data compromise. The low availability impact reflects that the crash is limited to the specific QUIC stream and does not necessarily crash the entire Envoy process.
Deep Dive & Mechanics
The vulnerability occurs in the interaction between Envoy’s HTTP Connection Manager (HCM) and the QUICHE library during push request handling. When a QUIC client sends a push request (a server-initiated stream), Envoy processes it through EnvoyQuicServerStream::OnInitialHeadersComplete(). If the HCM decides to stop reading from the stream (via StopReading()), it may destroy the associated ActiveStream object. However, QUICHE may still have pending callbacks for the same stream, such as delivering the initial headers. This race condition leads to a use-after-free when QUICHE accesses the already-freed ActiveStream memory.
The call stack provided in the CVE description confirms the crash occurs in EnvoyQuicServerStream::OnInitialHeadersComplete(). The root cause is a missing synchronization or lifecycle check between the HCM and QUICHE layers. Specifically, after StopReading(), the HCM should ensure that no further QUICHE callbacks are invoked for that stream, or that the callbacks are safely ignored.
Vulnerable vs. Patched Code
No official patch has been released. The vulnerable code path is in source/common/quic/envoy_quic_server_stream.cc:
// Vulnerable pseudo-code
void EnvoyQuicServerStream::OnInitialHeadersComplete(bool fin, size_t frame_len,
const QuicHeaderList& header_list) {
// ... process headers ...
// After StopReading(), ActiveStream may be destroyed
// but QUICHE still calls this function
}
A patched version would need to check if the stream has been stopped before processing headers:
// Patched pseudo-code
void EnvoyQuicServerStream::OnInitialHeadersComplete(bool fin, size_t frame_len,
const QuicHeaderList& header_list) {
if (read_side_closed() || !stream_delegate()) {
// Stream has been stopped; ignore callback
return;
}
// ... process headers safely ...
}
Until an official patch is available, users must rely on mitigations.
Exploitation & Lab Setup
Red Team
No public exploit code exists. To simulate the vulnerability in a lab:
- Setup: Deploy Envoy with QUIC/HTTP/3 enabled (e.g., using the
envoyproxy/envoy:latestimage with a configuration that listens on UDP 443). - Trigger: Use a custom QUIC client (e.g., modified
quic-goorlsquic) to send a push request followed immediately by aSTOP_SENDINGframe. The race condition requires precise timing. - Observation: Monitor Envoy logs for crashes or use a debugger to catch the use-after-free.
Example Python script using aioquic (conceptual):
import asyncio
from aioquic.asyncio import connect
from aioquic.quic.configuration import QuicConfiguration
async def trigger_cve():
configuration = QuicConfiguration(is_client=True)
async with connect("target", 443, configuration=configuration) as client:
# Send push request and immediately stop reading
stream_id = client.create_stream()
client.send_headers(stream_id, [(":method", "GET"), (":path", "/push")])
client.stop_sending(stream_id)
await asyncio.sleep(0.1)
asyncio.run(trigger_cve())
Blue Team
- Detection: Monitor for Envoy crashes with the specific call stack containing
EnvoyQuicServerStream::OnInitialHeadersComplete. Use logging to detect QUIC streams that are stopped prematurely. - Mitigation: Disable QUIC/HTTP/3 support in Envoy configuration if not required. Set
--disable-quicflag or remove QUIC listeners. - Hunting: Search for logs containing "use-after-free" or "QUIC stream crash". Correlate with network flows using UDP/443.
Indicators of Compromise (IOCs)
- Log Patterns:
EnvoyQuicServerStream::OnInitialHeadersCompletein crash dumpsActiveStreamdeallocation followed by QUICHE callback
- Network:
- QUIC streams with
STOP_SENDINGframes immediately after push request headers - UDP packets with abnormal stream termination patterns
- QUIC streams with
- File System:
- Core dumps from Envoy process (e.g.,
core.envoy.*)
- Core dumps from Envoy process (e.g.,
Detection Engineering
YARA Rule
rule CVE_2024_32974_Envoy_QUIC_UAF {
meta:
description = "Detects Envoy crash logs indicating use-after-free in QUIC stream handling"
author = "Valters IT"
date = "2025-04-10"
cve = "CVE-2024-32974"
strings:
$s1 = "EnvoyQuicServerStream::OnInitialHeadersComplete" ascii wide
$s2 = "use-after-free" ascii wide
$s3 = "ActiveStream" ascii wide
condition:
all of ($s1, $s2, $s3)
}
Sigma Rule
title: Envoy QUIC Use-After-Free Crash
id: 7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d
status: experimental
description: Detects Envoy crash events related to CVE-2024-32974
author: Valters IT
date: 2025-04-10
logsource:
product: envoy
service: proxy
detection:
selection:
EventID: 1 # Assuming crash event ID
Message|contains:
- "EnvoyQuicServerStream::OnInitialHeadersComplete"
- "use-after-free"
condition: selection
falsepositives:
- Legitimate crashes from other bugs
level: high
Suricata Rule
alert udp any any -> any 443 (msg:"CVE-2024-32974 Envoy QUIC Use-After-Free Attempt"; flow:to_server; content:"|00 00 00 00|"; depth:4; content:"|01|"; within:1; reference:cve,2024-32974; classtype:attempted-dos; sid:1000001; rev:1;)
Note: The Suricata rule is a placeholder; actual QUIC fingerprinting requires deeper packet inspection.
Remediation & Mitigation
- Disable QUIC/HTTP/3: If not required, disable QUIC support in Envoy by removing UDP listeners or setting
--disable-quic. - Upstream Patch: Monitor the Envoy GitHub repository for an official fix. Apply the patch as soon as available.
- Network Segmentation: Restrict access to Envoy QUIC endpoints to trusted clients only.
- Rate Limiting: Implement rate limiting on QUIC stream creation to reduce the impact of a DoS attack.
- Monitoring: Enable detailed logging for QUIC streams and set up alerts for crash patterns.
Valters IT
Senior DevSecOps & Cyber Threat Intelligence Expert