blog.rust.gay

Actix Web November RustSec advisories expose request-body decompression DoS paths

On November 6, 2026, the RustSec Advisory Database published two related vulnerability advisories affecting the Actix web stack: RUSTSEC-2026-0447 for actix-web and RUSTSEC-2026-0455 for actix-http. Both advisories describe denial-of-service paths where compressed HTTP request bodies could trigger large memory allocations before normal request-size controls stopped the work. The details matter because they cut through a common assumption in web service design: if an application sets an extractor size limit, it has bounded the cost of accepting a body.

The two advisories are distinct, but they point in the same direction. RUSTSEC-2026-0447 says body extractors did not pass their size limits to the decompression layer, so a small compressed request could cause a large allocation before the extractor rejected the decoded body. RUSTSEC-2026-0455 describes a Brotli-specific path in actix-http: with the compress-brotli feature enabled, the decoder accepted the non-standard large-window Brotli format, and a crafted stream could grow an internal buffer to about 1 GiB before the decoded output reached the configured size limit. RustSec reports that an 850-byte request can cause that allocation, and that concurrent requests can exhaust process or host memory.

For teams running Actix-based APIs, the immediate action is straightforward: read the advisories, identify whether request-body decompression is enabled in the dependency graph, and upgrade to the patched releases named by RustSec. The longer lesson is architectural. Decompression, parsing, authentication, and business logic do not happen at the same time, and a limit enforced late in the pipeline may not protect the resources consumed early in the pipeline.

What RUSTSEC-2026-0447 says about extractor limits

RUSTSEC-2026-0447 was reported and issued on November 6, 2026. The advisory applies to the actix-web package and classifies the issue as a vulnerability in the denial-of-service category. RustSec’s description is short but specific: body extractors did not pass their size limits to the decompression layer. Because of that gap, a small compressed request could cause a large allocation before the extractor rejected the decoded body. RustSec states that a remote attacker can use this behavior to exhaust memory or CPU resources and cause denial of service.

The affected scope is also specific. The advisory says the issue affects applications that read compressed request bodies with the corresponding compression feature enabled. That phrasing is useful for triage because it separates two questions that are easy to blur together. The first question is whether an application uses actix-web extractors such as JSON, form, string, or raw bytes handlers. The second is whether the deployment accepts compressed request bodies through enabled compression support. An Actix application that never accepts compressed request bodies has a different exposure profile from one that accepts gzip, deflate, or Brotli payloads from clients.

RustSec lists the fix path as upgrading to actix-web 4.18.2 or later with actix-http 3.20.1 or later. It also references commit 0d0be61bd757027bfcecbc53df1b7a600f21ecd0 in the actix/actix-web repository. The advisory gives a workaround: reject compressed request bodies at a reverse proxy or in middleware before body extraction. That workaround is notable because it moves the decision point earlier than application extractors. If the goal is to stop expensive decompression work, the control must run before the server commits to decompressing the body.

The practical implication is that a configured extractor limit is not, by itself, a complete statement about memory safety under adversarial compression. Developers often treat limits on JSON or form payloads as a single guardrail: the framework will read at most N bytes, parse them, and hand the result to the handler. Compression complicates that model because the bytes on the wire and the bytes after decoding are different objects with different costs. RUSTSEC-2026-0447 describes the case where the limit existed, but it was not communicated to the layer that expanded the data.

What RUSTSEC-2026-0455 adds about Brotli large windows

RUSTSEC-2026-0455, also reported and issued on November 6, 2026, applies to actix-http. It is also categorized as denial of service. The advisory focuses on Brotli decompression when the compress-brotli feature is enabled. According to RustSec, the decoder accepts the non-standard large-window Brotli format. A crafted stream can cause the decoder’s internal buffer to grow to about 1 GiB before the decoded output reaches the configured size limit.

RustSec includes two details that make the risk concrete. First, it says an 850-byte request can cause this allocation. Second, it says concurrent requests can exhaust process or host memory. Those numbers are not a full exploit benchmark, and the advisory does not provide a weaponized payload, but they are enough to show the asymmetry: the attacker-controlled input can be tiny compared with the memory consumed while decoding. In denial-of-service analysis, that ratio matters more than whether the request eventually produces a valid application object.

The advisory also explains why application-level checks do not help. It states that Actix Web enables Brotli support by default, and that applications reading request bodies through Bytes, String, Json, or Form can be affected even when extractor size limits are configured. The allocation occurs before the handler runs, so authentication performed in the handler does not prevent it. That last sentence is especially important for API teams that rely on handler middleware, route guards, or token validation inside request handlers as if they were front doors. If the expensive allocation happens before the handler executes, authentication is too late to protect memory.

RustSec’s fix guidance for RUSTSEC-2026-0455 is to upgrade to actix-http 3.20.3 or later. The advisory references commit 61c6a15c1c0e505a5cd6842610a5f1faea432a83. Workarounds include rejecting requests with Content-Encoding: br at a reverse proxy or in middleware before body extraction, or disabling the compress-brotli feature throughout the dependency graph. The “throughout the dependency graph” phrase is a reminder that Cargo features can be enabled transitively. A service that does not think of itself as using Brotli request decompression may still have the feature active because of a dependency choice or default feature set.

Why decompression limits fail when layers do not share them

The two Actix advisories fit a broader class of web security bugs: the system has a limit, but the limit is attached to the wrong stage. Request handling is a pipeline. A server accepts bytes from the network, interprets framing, decodes transfer or content encodings, applies protocol-specific parsing, enforces application limits, authenticates the caller, and finally runs business logic. Each stage consumes different resources. Network buffers, decompressor state, parser scratch space, JSON DOMs, database queries, and handler allocations all have different sizes and lifetimes.

Compression is dangerous when a later stage owns the budget for an earlier stage. A JSON extractor might reasonably reject a decoded body larger than 1 MiB. That rule protects the JSON parser and the application from oversized objects. It does not automatically protect the decompressor from allocating a large sliding window, output buffer, or intermediate state while trying to discover that the decoded output would exceed 1 MiB. RUSTSEC-2026-0447 describes exactly that ordering problem: the extractor had limits, but the decompression layer did not receive them.

RUSTSEC-2026-0455 adds another dimension: format features that are valid enough for a decoder to accept can still be operationally hostile in a server context. Brotli’s large-window behavior, as described by the advisory, caused an internal buffer to grow far beyond what the request size suggested. The issue is not that Rust made memory safety impossible; the affected code is still memory-safe Rust in the sense that it is not described as memory corruption. The issue is resource safety. A process can be perfectly memory-safe and still be forced into an out-of-memory condition by untrusted input.

This distinction is worth stating plainly in Rust security discussions. Rust eliminates classes of bugs such as use-after-free and out-of-bounds writes when code stays within safe boundaries, but it does not automatically bound CPU, memory, file descriptors, queue depth, or algorithmic complexity. Actix is a widely used Rust web framework, and these advisories are a reminder that safe systems programming languages still need careful resource accounting at trust boundaries.

How operators should triage an Actix service

The first triage step is dependency inspection. Teams should determine whether their services depend on actix-web, actix-http, or both, and which versions are resolved in Cargo.lock. A direct dependency on actix-web may pull in actix-http transitively. The relevant advisory fixes are version-specific: RUSTSEC-2026-0447 names actix-web 4.18.2 or later with actix-http 3.20.1 or later, while RUSTSEC-2026-0455 names actix-http 3.20.3 or later. Because the two advisories were issued on the same day and touch the same request decompression area, it is sensible to update to patched releases that satisfy the stated fixes rather than treating the versions as independent checkboxes.

The second step is feature inspection. RUSTSEC-2026-0447 applies when compressed request bodies are read with the corresponding compression feature enabled. RUSTSEC-2026-0455 names the compress-brotli feature and notes that Actix Web enables Brotli support by default. Teams should inspect Cargo.toml for default features, explicit feature flags, and middleware or extractor behavior that implies request decompression. They should also check reverse proxies, ingress controllers, and API gateways. Some deployments terminate or normalize compression at the edge; others pass Content-Encoding through to application servers.

The third step is exposure assessment. A public endpoint that accepts POST, PUT, or PATCH bodies from unauthenticated clients has a different risk profile from an internal admin endpoint behind mTLS and network policy. That does not mean internal endpoints are irrelevant. RustSec’s note that allocation occurs before the handler runs, and before handler-level authentication, means that any route reachable by an attacker who can send HTTP requests to the process may be able to trigger the expensive path. “Authenticated in the handler” is not the same control as “cannot reach the decompressor without passing an edge check.”

The fourth step is workload behavior under concurrency. The advisories describe memory exhaustion, and RUSTSEC-2026-0455 explicitly mentions concurrent requests. A service that survives a single large allocation in a test environment may still fail when many requests arrive together. Operators should consider process memory limits, container limits, pod density, and whether an out-of-memory kill would affect colocated workloads. The right mitigation is patching, but understanding blast radius helps decide how urgently to deploy and whether to apply temporary edge controls.

Remediation choices and their trade-offs

The best remediation is to upgrade to patched versions, as RustSec states. Patching fixes the vulnerable behavior in the library code path instead of asking every deployment to remember a special-case rule. It also avoids long-lived exceptions that become invisible after an incident fades from attention.

Workarounds are still useful when a rollout cannot happen immediately. Rejecting compressed request bodies before body extraction, as recommended in RUSTSEC-2026-0447, can be effective if the application does not need clients to send compressed payloads. Rejecting Content-Encoding: br before body extraction, or disabling compress-brotli throughout the dependency graph, addresses the specific Brotli path described in RUSTSEC-2026-0455. These controls are easiest to reason about at a reverse proxy because the proxy can make a simple request-level decision before forwarding bytes to the application.

Each workaround has trade-offs. Disabling compressed request bodies may break clients that were legitimately compressing large JSON or form submissions. Blocking Brotli only may leave other compression behavior in place while removing the path named by the advisory. Feature changes in Cargo require careful verification because features can be unified across dependencies. The advisory’s warning to disable compress-brotli throughout the dependency graph should be read as an instruction to inspect the final resolved feature set, not merely the top-level crate’s manifest.

Testing after remediation should include more than “the service starts.” A good check confirms the resolved crate versions, verifies that expected request encodings still behave correctly for trusted clients, and exercises size limits with compressed and uncompressed bodies. The goal is not to reproduce the denial-of-service condition in production; it is to confirm that the deployment has the patched code path and that any temporary edge rule does what operators think it does.

What this means for Rust web security

Actix has long been part of the Rust web conversation because it combines performance, an actor-influenced heritage, and an ergonomic extractor model. These advisories do not imply that Rust web frameworks are uniquely dangerous, and they do not provide evidence that memory-unsafe code execution occurred. They do show that high-performance web stacks still have to treat request decoding as an adversarial input problem.

The useful takeaway for maintainers is to propagate limits across layers. If an extractor accepts a maximum body size, the decompressor, parser, and buffering layers need compatible budgets. If a decoder supports optional formats or unusually large windows, the server’s default configuration should reflect operational risk, not just format completeness. If a handler performs authentication, the framework should not make authentication the first effective gate against resource exhaustion.

The useful takeaway for application teams is to read RustSec advisories as operational design feedback, not only as patch notices. RUSTSEC-2026-0447 and RUSTSEC-2026-0455 describe a boundary between convenience and cost: accepting compressed request bodies is convenient for clients, but every accepted encoding becomes part of the server’s attack surface. The right response is usually not to avoid compression forever. It is to make decompression limits explicit, keep dependencies patched, and place cheap rejection rules before expensive work.

Conclusion

The November 6, 2026 RustSec advisories for actix-web and actix-http describe a pair of denial-of-service risks rooted in request-body decompression. RUSTSEC-2026-0447 reports that extractor size limits were not passed to the decompression layer, allowing a small compressed request to trigger a large allocation before rejection. RUSTSEC-2026-0455 reports that large-window Brotli decoding in actix-http could grow an internal buffer to about 1 GiB before the configured size limit applied, with RustSec noting that an 850-byte request can cause the allocation and that the work happens before handler-level authentication.

For Actix users, the path forward is clear: apply the patched releases named by RustSec, review whether compressed request bodies and Brotli are enabled across the dependency graph, and use edge or middleware rejection as a temporary control when needed. For the wider Rust ecosystem, the advisories are a practical reminder that memory safety does not remove the need for resource limits. In web servers, the bytes that look small on the wire can become expensive before the application ever sees a parsed request.

Sources


← back to posts