GitHub Security Advisory: GHSA-84xm-r438-86px
Package: github.com/envoyproxy/envoy (GO)
Severity: MODERATE (CVSS 5.9)
CWE: CWE-416: Use After Free
Vulnerable versions: = 1.37.0
Patched in: unpatched

Summary: Envoy: HTTP - filter chain execution on reset streams causing UAF crash

Details:
**Note:**
This vulnerability was originally reported to the Google OSS VRP (Issue ID: [477542544](https://issuetracker.google.com/issues/477542544)). The Google Security Team requested that I coordinate directly with the Envoy maintainers for triage and remediation. I am submitting this report here to facilitate that process.

**Technical Details**
I have identified a logic vulnerability in Envoy's HTTP connection manager (`FilterManager`) that allows for **Zombie Stream Filter Execution**. This issue creates a "Use-After-Free" (UAF) or state-corruption window where filter callbacks are invoked on an HTTP stream that has already been logically reset and cleaned up.

**Mechanism:**
The vulnerability resides in `source/common/http/filter_manager.cc` within the `FilterManager::decodeData` method.

When an HTTP/2 stream encounters a reset condition (e.g., `StreamIdleTimeout`, `OverloadManager` limits, or a local reset triggered by a filter), Envoy calls `onResetStream`. This method:
1.  Sets the internal state `state_.saw_downstream_reset_ = true`.
2.  Invokes `onDestroy()` on all filters in the chain (allowing them to release resources/pointers).
3.  Schedules the `ActiveStream` object for **deferred deletion** (cleanup happens later in the event loop).

**The Flaw:**
The `ActiveStream` object remains valid in memory during the deferred deletion window. If a `DATA` frame arrives on this stream immediately after the reset (e.g., in the same packet processing cycle), the HTTP/2 codec invokes `ActiveStream::decodeData`, which cascades to `FilterManager::decodeData`.

`FilterManager::decodeData` **fails to check the `saw_downstream_reset_` flag**. It iterates over the `decoder_filters_` list and invokes `decodeData()` on filters that have already received `onDestroy()`.

**Root Cause Code Location:**
File: `source/common/http/filter_manager.cc`
Function: `FilterManager::decodeData`

```cpp
void FilterManager::decodeData(...) {
  if (stopDecoderFilterChain()) { return; }

  // Vulnerability: Missing check for state_.saw_downstream_reset_
  // Execution proceeds into the loop even if the stream is logically dead.

  auto trailers_added_entry = decoder_filters_.end();
  for (; entry != decoder_filters_.end(); entry++) {
      // ... calls (*entry)->handle_->decodeData(data) on destroyed filters ...
  }
}
```

**Suggested Fix:**
Add an explicit state check at the beginning of `FilterManager::decodeData`.

```cpp
// Prevent execution on streams that have been reset but not yet destroyed.
if (state_.saw_downstream_reset_) {
  return;
}
```

---

## Impact Analysis

**Who can exploit this:**
Any remote attacker capable of establishing an HTTP/2 or HTTP/3 connection. No privileges/authentication required.

**Impact & Gain:**
**1. Memory Corruption & Potential Remote Code Execution:**
While the immediate symptom is a crash (DoS), the underlying primitive is a **Use-After-Free (CWE-416)**.
* **Mechanism:** When `onDestroy()` is called on filters (e.g., Lua, Wasm,