# Interim mitigations

Controls that reduce exposure while a patch is impossible or not yet deployed. None of them replaces
the update: they narrow the reachable surface, they do not remove the vulnerable decoder, and every
one of them can be bypassed by a path the operator did not think of.

## 1. Reject Brotli request bodies at the edge

The cheapest control: refuse `Content-Encoding: br` before it reaches application code.

```nginx
# nginx
if ($http_content_encoding ~* "(^|,)\s*br(\s*,|$)") {
    return 415;
}
```

```yaml
# conceptual WAF rule
name: block_brotli_request_encoding
match:
  request_headers:
    Content-Encoding: "(?i)(^|,)\s*br(\s*,|$)"
action: block
response_status: 415
log: true
```

Two properties make this a stopgap and not a fix:

- it covers **inbound** bodies only; every outbound fetch that decompresses `br` stays exposed;
- it breaks legitimate clients that send Brotli, so it belongs on endpoints that do not need it, and
  it must be measured against real traffic.

## 2. Know the framework defaults

On Node.js, Express 5 and `body-parser` 2 decompress Brotli request bodies by default: the `inflate`
option defaults to `true` for the JSON, raw, text and URL-encoded parsers. An endpoint that "never
supported Brotli" may therefore decode it anyway. Disable or control that behaviour explicitly for
untrusted routes.

The same question applies to every framework that advertises transparent request decompression. Read
the default, do not assume it.

## 3. Restrict outbound decompression

For clients, the risk is the response: a malicious or compromised server answers with `br` and the
HTTP client decodes it. This is the path that mattered on our hosts — WordPress Requests, SimplePie
and Guzzle all set `CURLOPT_ENCODING` to an empty string, which means "accept everything".

Priority targets for this restriction: crawlers, webhook consumers, URL-preview services, document
processors, and any integration that fetches URLs a third party supplied.

## 4. Isolate the decoding workload

If Brotli decompression is a business requirement and the patch is not yet deployed, move the risk
instead of arguing about it:

- run parsing and decompression in a separate low-privilege worker;
- give it a dedicated container with no cloud credentials and minimal secrets;
- apply restrictive egress policy;
- deny access to internal networks and the metadata endpoint;
- use a separate service identity with short-lived credentials.

An isolated decoder that crashes takes down a worker, not the platform.

## 5. Watch for the symptoms

A vulnerable decode path usually shows itself before anyone proves exploitation. Collect and
correlate:

- application logs with Brotli decompression errors;
- process crashes, `SIGSEGV`, abnormal exits and worker restarts;
- reverse-proxy requests carrying `Content-Encoding: br`;
- Node.js and Bun restarts following malformed compressed input;
- Envoy or Istio proxy crashes and restarts;
- unexpected outbound connections after a compressed request was processed;
- container restarts, OOM kills and crash loops.

None of these is proof. All of them are cheaper to notice than a heap corruption that succeeded.

## 6. Post-mitigation validation

```bash
# the reject rule answers where decompression is disabled
curl -i -X POST https://service.example/api \
  -H 'Content-Encoding: br' \
  --data-binary @sample.br

# the runtime inside the deployed container, not in the repository
docker exec CONTAINER node --version

# the library inside the deployed container
docker exec CONTAINER sh -c \
  'dpkg -l | grep -Ei "brotli|libbrotli" || apk info -a | grep -i brotli'
```

Expected: `415` from the first command, a patched version from the second, a fixed package from the
third. Anything else means the mitigation or the patch is not in the path you think it is.

## 7. What each control does not cover

| Control | Covers | Leaves exposed |
|---|---|---|
| 415 at the edge | inbound bodies through that proxy | every outbound decode, every direct-to-service path |
| framework `inflate` disabled | that framework's request parsing | other services, outbound clients |
| outbound decode restricted | that client's fetches | inbound paths, other clients |
| workload isolation | blast radius | the vulnerability itself |
| monitoring | detection speed | the exploit |

Next: [Operating runbook](10-Operations) — the tool that automates the Debian and Ubuntu path.
