Skip to content

Exclude Brotli from the default AutomaticDecompression while CVE-2026-111497 is unpatched in .NET - #2419

Open
K3UL wants to merge 2 commits into
restsharp:devfrom
K3UL:fix/brotli-default-cve-2026-111497
Open

K3UL wants to merge 2 commits into
restsharp:devfrom
K3UL:fix/brotli-default-cve-2026-111497

Conversation

@K3UL

@K3UL K3UL commented Oct 24, 2026 •

Copy link
Copy Markdown

Issue

Resolves #2420

Why

CVE-2026-111497 (CVSS 4.0: 9.2) is an out-of-bounds write in Google's Brotli C decoder, versions 1.0.3–1.2.0. The .NET runtime vendors that decoder (src/native/external/brotli, currently 1.1.0 on release/9.0–main, 1.0.9 on release/8.0) and exposes it through HttpClient automatic decompression. As of 2026-10-24 no .NET servicing release contains the fix and no public branch of dotnet/runtime has it (checked: the BLOCK_SWITCH error code and the DecodeBlockTypeAndLength signature change are absent on every branch touched this month).

The bug is reachable from the client side: a server the application calls replies with a crafted Content-Encoding: br body, and the client's automatic decompression feeds it to the decoder. Imperva demonstrated code execution through this path on Node.js; public PoCs exist.

HttpClientHandler.AutomaticDecompression defaults to None, so a plain HttpClient is not exposed. RestClientOptions.AutomaticDecompression defaults to All, so every RestClient built with default options is, without the caller ever having mentioned Brotli.

What

  • RestClientOptions.AutomaticDecompression default on .NET changes from All to GZip | Deflate. .NET Framework (GZip) is unchanged.
  • XML docs, configuration.md and the changelog explain why and how to opt back in.
  • Two integration tests: a default client neither advertises br nor decodes a br response; a client with All still does. All CompressionTests pass on net10.0.

Impact on users

  • Servers that send Brotli also send gzip when asked, so default clients keep working and receive gzip instead. Slightly larger transfers; no functional change.
  • Anyone who wants Brotli back sets AutomaticDecompression = DecompressionMethods.All.
  • This is a behavior change and should ship as a minor version (114.2).

Follow-up

Once Microsoft ships fixed runtimes (8.0.x / 9.0.x / 10.0.x servicing), a follow-up PR can decide whether to return the default to All. Because RestSharp supports runtimes that will stay unpatched (apps pinned to older patch levels, self-contained deployments), I'd argue for keeping GZip | Deflate as the permanent default and treating Brotli as opt-in, but that's a separate discussion.

Alternative if this is too invasive

A docs-only change: keep All, add the warning block from configuration.md and a pinned security advisory recommending GZip | Deflate until patched. Protects only readers of the docs, but is non-breaking.

References:

@qodo-free-for-open-source-projects

Copy link
Copy Markdown
Contributor

PR Summary by Qodo

Exclude Brotli from default .NET decompression

🐞 Bug fix 🧪 Tests 📝 Documentation 🕐 20-40 Minutes

Grey Divider

AI Description

• Default .NET clients to gzip and deflate to avoid the vulnerable runtime Brotli decoder.
• Preserve explicit Brotli opt-in and the existing .NET Framework default.
• Document the behavior change and test default and opt-in responses.
Diagram

graph TD
  A["RestClientOptions"] --> B{"Brotli enabled?"} -->|Default: no| C["GZip and Deflate"] --> E["HttpClientHandler"] --> F["Accept-Encoding"] --> G["HTTP server"] --> H["Response handling"]
  B -->|Explicit opt-in| D["All methods"] --> E
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Publish a warning without changing the default
  • ➕ Avoids a default behavior change for existing clients.
  • ➖ Default clients remain exposed until users read the warning and change their configuration.

Recommendation: Keep the proposed safer default: it removes Brotli exposure for default clients while retaining an explicit opt-in. A documentation-only warning cannot protect clients whose callers take no action.

Files changed (4) +69 / -3

Bug fix (1) +9 / -2
RestClientOptions.csRemove Brotli from the default .NET methods +9/-2

Remove Brotli from the default .NET methods

• Changes the .NET AutomaticDecompression initializer from All to GZip | Deflate while leaving the .NET Framework initializer at GZip. XML remarks explain the risk and explicit opt-in.

src/RestSharp/Options/RestClientOptions.cs

Tests (1) +39 / -0
CompressionTests.csTest default Brotli exclusion and explicit opt-in +39/-0

Test default Brotli exclusion and explicit opt-in

• Adds .NET 8+ integration tests asserting that a default client does not advertise or decode Brotli, while a client configured with All still decodes it.

test/RestSharp.Tests.Integrated/CompressionTests.cs

Documentation (2) +21 / -1
configuration.mdExplain the Brotli default and opt-in +15/-1

Explain the Brotli default and opt-in

• Updates the options reference with the .NET and .NET Framework defaults. Adds a CVE warning and an example for explicitly restoring Brotli on a patched runtime.

docs/docs/advanced/configuration.md

changelog.mdRecord the v114.2 decompression behavior change +6/-0

Record the v114.2 decompression behavior change

• Adds release notes explaining the Brotli exclusion, its security rationale, the unchanged .NET Framework default, and how to opt back in.

docs/docs/changelog.md

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. Brotli-only services return unreadable content ✓ Resolved
Description
The Brotli guidance says servers that support Brotli also support gzip, but the new default cannot
decode a response sent only with Content-Encoding: br. When such a server returns Brotli despite
the client not advertising it, RestSharp returns the compressed bytes as response content, as the
new integration test demonstrates; a server that refuses the request instead cannot provide the
promised gzip fallback either.
Code

docs/docs/advanced/configuration.md[203]

+Servers that support Brotli also support gzip, so responses arrive gzip-encoded instead. If you need Brotli and your runtime includes the fix, opt in explicitly:
Evidence
The new default configures the handler without Brotli. The added test has a server return Brotli and
confirms that the default client receives the compressed bytes rather than the decoded content,
contradicting the unconditional fallback claim.

docs/docs/advanced/configuration.md[200-209]
src/RestSharp/Options/RestClientOptions.cs[110-115]
src/RestSharp/RestClient.cs[225-229]
test/RestSharp.Tests.Integrated/CompressionTests.cs[80-92]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The documentation promises gzip responses from every Brotli-capable server, but the new default cannot guarantee that fallback. A server that returns only Brotli leaves the response undecoded, while one that refuses other encodings cannot return gzip.
## Fix Focus Areas
- docs/docs/advanced/configuration.md[200-209]
- test/RestSharp.Tests.Integrated/CompressionTests.cs[80-92]
## Recommended Fix
Qualify the gzip fallback as dependent on server support and explain that Brotli-only responses will not be decoded by default. Keep the security warning and describe explicit opt-in only for patched runtimes.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Tip of the day
💡 Did you know, you can choose which labels appear on a finding, and whether they show icons or text

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread docs/docs/advanced/configuration.md Outdated
K3UL and others added 2 commits October 24, 2026 17:07
The Brotli decoder vendored in the .NET runtime (System.IO.Compression.Native)
has an out-of-bounds write, CVE-2026-111497, reachable from a crafted
Content-Encoding: br response. No fixed runtime has shipped. With
AutomaticDecompression defaulting to All, every RestClient built with default
options advertised br and routed untrusted responses through that decoder.

Default is now GZip | Deflate on .NET. Opting back in is one line:
AutomaticDecompression = DecompressionMethods.All. .NET Framework default
(GZip) is unchanged.
@K3UL
K3UL force-pushed the fix/brotli-default-cve-2026-111497 branch from 44139b4 to 90c3011 Compare October 24, 2026 15:07
@K3UL

K3UL commented Oct 24, 2026

Copy link
Copy Markdown
Author

@dotnet-policy-service agree

@sonarqubecloud

Copy link
Copy Markdown

This branch has not been deployed

No deployments
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.

Default AutomaticDecompression = All routes responses through the Brotli decoder affected by CVE-2026-111497

1 participant