Skip to content

Fix PRIORITY flood bypass - #45077

Merged
yanavlasov merged 16 commits into
envoyproxy:mainfrom
etruong42:priorityflood
Jun 10, 2026
Merged

Fix PRIORITY flood bypass#45077
yanavlasov merged 16 commits into
envoyproxy:mainfrom
etruong42:priorityflood

Conversation

@etruong42

@etruong42 etruong42 commented May 14, 2026

Copy link
Copy Markdown
Contributor

Limit number of PRIORITY frames based on active_streams rather than the currently bypassable limit based on the cumulative number of streams ever opened on a connection (open_streams).

Add a test that prevents regression.

Commit Message:
Additional Description:
Risk Level:
Testing:
Docs Changes:
Release Notes:
Platform Specific Features:
[Optional Runtime guard:]
[Optional Fixes #Issue]
[Optional Fixes commit #PR or SHA]
[Optional Deprecated:]
[Optional API Considerations:]

@repokitteh-read-only

Copy link
Copy Markdown

As a reminder, PRs marked as draft will not be automatically assigned reviewers,
or be handled by maintainer-oncall triage.

Please mark your PR as ready when you want it to be reviewed!

🐱

Caused by: #45077 was opened by etruong42.

see: more, trace.

Limit number of PRIORITY frames based on active_streams rather than
cumulative number of streams ever opened on a connection.

Add a test that prevents regression.

Signed-off-by: Ethan Truong <ethantruong@google.com>
@etruong42
etruong42 marked this pull request as ready for review May 19, 2026 13:35
@etruong42

Copy link
Copy Markdown
Contributor Author

/assign yanavlasov

@yanavlasov

Copy link
Copy Markdown
Contributor

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the HTTP/2 protocol constraints to use the number of currently active streams (active_streams_) instead of the cumulative opened streams (opened_streams_) when validating inbound frame limits for PRIORITY and WINDOW_UPDATE frames. It also introduces a new integration test to verify flood mitigation behavior. The reviewer identified a critical correctness issue where using a decreasing active stream count against cumulative frame counters will eventually trigger false-positive flood detections on long-lived connections. A code suggestion was provided to decrement the cumulative frame allowances when a stream is closed and to add defensive checks.

Comment thread source/common/http/http2/protocol_constraints.h

@yanavlasov yanavlasov left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/wait


if (inbound_priority_frames_ >
static_cast<uint64_t>(max_inbound_priority_frames_per_stream_) * (1 + opened_streams_)) {
static_cast<uint64_t>(max_inbound_priority_frames_per_stream_) * (1 + active_streams_)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will need a runtime guard as it has potential to break existing traffic. Can you add one please?

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Signed-off-by: Ethan Truong <etruong42@gmail.com>
Signed-off-by: Ethan Truong <ethantruong@google.com>
@repokitteh-read-only

Copy link
Copy Markdown

CC @envoyproxy/runtime-guard-changes: FYI only for changes made to (source/common/runtime/runtime_features.cc).

🐱

Caused by: #45077 was synchronize by etruong42.

see: more, trace.

Signed-off-by: Ethan Truong <ethantruong@google.com>
etruong42 added 3 commits June 2, 2026 09:48
Signed-off-by: Ethan Truong <ethantruong@google.com>
Signed-off-by: Ethan Truong <ethantruong@google.com>
Signed-off-by: Ethan Truong <ethantruong@google.com>
Signed-off-by: Ethan Truong <ethantruong@google.com>
etruong42 added 4 commits June 4, 2026 13:50
Signed-off-by: Ethan Truong <ethantruong@google.com>
Signed-off-by: Ethan Truong <ethantruong@google.com>
Signed-off-by: Ethan Truong <ethantruong@google.com>
@etruong42
etruong42 requested a review from yanavlasov June 8, 2026 18:55

@yanavlasov yanavlasov left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me. Please add flood tests for WINDOW_UPDATE since the logic for the check changed as well.

/wait

Signed-off-by: Ethan Truong <ethantruong@google.com>
etruong42 added 4 commits June 9, 2026 08:51
Signed-off-by: Ethan Truong <ethantruong@google.com>
Signed-off-by: Ethan Truong <ethantruong@google.com>
Signed-off-by: Ethan Truong <ethantruong@google.com>
@etruong42
etruong42 requested a review from yanavlasov June 9, 2026 19:47
@yanavlasov
yanavlasov merged commit 4d30b6c into envoyproxy:main Jun 10, 2026
27 of 28 checks passed
nezdolik pushed a commit to nezdolik/envoy that referenced this pull request Jun 16, 2026
Limit number of PRIORITY frames based on active_streams rather than the
currently bypassable limit based on the cumulative number of streams
ever opened on a connection (`open_streams`).

Add a test that prevents regression.

Signed-off-by: Ethan Truong <ethantruong@google.com>
shumkov added a commit to dashpay/docker-envoy that referenced this pull request Jul 26, 2026
… bypass (#4)

v1.35.11 predates Envoy's 2026-06-23 security batch of 15 advisories.
v1.39.0 closes all of them plus an HTTP/2 flood-protection bypass that was
never backported to any patch line.

Denial of service / crash / memory exhaustion:
  - HTTP/2 PRIORITY and WINDOW_UPDATE flood bypass (no CVE assigned):
    limits scaled with the cumulative count of streams ever opened, so an
    attacker churning streams inflated the budget without bound and never
    tripped the limit. Now scales with active streams and retires on close.
  - GHSA-p7c7-7c47-pwch (high): HTTP/3 QPACK blocked-decoding DoS
  - CVE-2026-48042 (high): stack overflow in destructor of highly nested JSON
  - CVE-2026-48044 (high): zstd RLE zip bomb, decompressor memory explosion
  - CVE-2026-47207: crash on multiple ext_proc responses in one gRPC message
  - CVE-2026-47221: null pointer deref in router internal redirects
  - CVE-2026-47204: grpc_stats segfault on Connect requests to direct_response
  - CVE-2026-48090: OAuth2 use-after-free on late async token completion
  - CVE-2026-48497: abnormal process termination in DNS UDP filter
  - CVE-2026-48706: heap buffer overflow in TcpStatsdSink on large stat names

Also fixed:
  - CVE-2026-48743 (high): HTTP/3 to HTTP/1 request smuggling
  - CVE-2026-47778: embedded NUL TLS SAN truncation, auth bypass
  - CVE-2026-47775: OAuth2 padding oracle, plus opt-in AES-256-GCM cookies
  - CVE-2026-47692: PROXY protocol v2 skipped-TLV upstream spillover
  - CVE-2026-47261: wasmtime bump, upstream dependency

Why 1.39.0 rather than the minimal 1.35.13 bump: the PRIORITY/WINDOW_UPDATE
flood fix shipped as a behavior change under the runtime guard
envoy.reloadable_features.http2_flood_protection_active_streams, not as an
advisory, and was not backported to 1.35.13, 1.36.9, 1.37.5 or 1.38.3. It is
present and enabled by default only in 1.39.0, verified by inspecting
source/common/http/http2/protocol_constraints.h at each tag. The gateway
terminates HTTP/2 from untrusted clients, so this path is reachable.
Moving to 1.39.0 also resets the 12-month backport window; the 1.35 line
reached the end of it (v1.35.0 shipped 2025-07-23).

CVE-2026-47205 (>=1.36) and CVE-2026-47220 (>=1.37.0) never affected 1.35,
but both are fixed in 1.39.0, so the line move adds no new exposure.

Behavior changes in 1.39.0 to validate against gateway config: HeaderMatcher
now evaluates repeated headers individually rather than comma-joined, the TLS
inspector rejects client TLS versions outside 1.0-1.3, enforce_rsa_key_usage
is always enforced, and OpenTelemetry tracing honors Envoy's sampling
decision. The Bazel 8 change does not apply, as this consumes the prebuilt
image.

Base image only. The python3 install, hot-restarter scripts and ENTRYPOINT
are unchanged. No test added: base-image version bump, and the repo has no
test suite. Verified by building the image, confirming the binary reports
1.39.0 with the flood-protection guard compiled in, and exercising the
SIGHUP hot restart end to end: a new epoch started workers while the old
process drained listeners, which is the zero-downtime path dashmate uses.

Refs: https://github.com/envoyproxy/envoy/releases/tag/v1.39.0
Refs: envoyproxy/envoy#45077

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants