Cap Zstandard request decompression window at 8 MB#67688
Open
BrennanConroy wants to merge 1 commit into
Open
Conversation
Set MaxWindowLog to 23 (8 MB) on the request decompression provider's ZstandardDecompressionOptions, as required by RFC 9659 for the "zstd" HTTP content coding. This bounds the memory the decoder can be forced to allocate for a single request. Default streaming compression uses a window of at most 2 MB and is unaffected; payloads produced with a larger window (for example, "zstd --long") will fail to decompress. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Caps Zstandard (zstd) request-body decompression window size to the RFC 9659 maximum (8 MiB / windowLog 23) to mitigate decompression-bomb style memory DoS from untrusted clients, by configuring the runtime decoder’s new ZstandardDecompressionOptions.MaxWindowLog.
Changes:
- Configure
ZstandardStreamrequest decompression withZstandardDecompressionOptions { MaxWindowLog = 23 }. - Add an integration-style middleware test that compresses with an oversized window (windowLog 24) and asserts decompression fails.
- Document the rationale (RFC requirement and browser behavior) inline in the provider.
Show a summary per file
| File | Description |
|---|---|
| src/Middleware/RequestDecompression/src/ZstandardDecompressionProvider.cs | Uses ZstandardDecompressionOptions.MaxWindowLog = 23 to cap decoder window to 8 MiB per RFC 9659. |
| src/Middleware/RequestDecompression/test/RequestDecompressionMiddlewareTests.cs | Adds coverage to ensure oversized zstd windows are rejected (throws during request processing). |
Copilot's findings
- Files reviewed: 2/2 changed files
- Comments generated: 0
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Cap the Zstandard request decompression window at 8 MB (windowLog 23).
Description
The request decompression middleware decodes
zstdrequest bodies from untrusted clients. The zstd decoder sizes its window buffer from the frame header, and the native default allows windows up to 128 MB. That lets a small compressed request force a large decoder allocation, which is a decompression-bomb style DoS vector.This wires up the new
System.IO.Compression.ZstandardDecompressionOptions.MaxWindowLog(from dotnet/runtime#129768) and sets it to 23 (8 MB) internally on the request decompression provider. 8 MB is the maximum window RFC 9659 permits for the HTTPzstdcontent coding, and it matches what browsers such as Chromium enforce. A request that advertises a larger window now fails to decompress.This is intentionally an internal change with no new public API. The related API proposal (#67476) to expose these options was not approved, so the window is capped at the RFC-mandated value with no configuration knob for now.
Notes for reviewers:
zstd --long, ultra levels, or an explicitWindowLog > 23) are rejected.IOException("Data requires too much memory for decoding..."). The middleware lets it propagate, matching how it already surfaces other decode failures. The added test asserts this.Related to #67476