# CRLF injection into headers and config

User input reaching headers, config files, or proxy directives without newline validation

_Area: Web infrastructure and server-side requests. Seen in 5 disclosed reports; 4 confirmed bounties, median $5,500, range $600-$20,000; latest 2026-08-05. Updated 2026-10-23._

## How it works
A value is placed into an HTTP header, a config file, or a proxy directive without rejecting CR/LF. The receiving parser treats the newline as a line break, so attacker text becomes a new header, a new config directive, or a split request. The broken assumption is that a field is "just a string" safe to concatenate; in fact the sink is a line-oriented format where newline is syntax. This spans header sinks and adjacent line-oriented sinks like INI config [E3](https://bugbountylibrary.com/r/h1%3A1200647.md).

## Where it shows up
- Proxy variables decoded before use, e.g. nginx `$uri` in `proxy_pass`, `return`, `redirect` [E1](https://bugbountylibrary.com/r/blog%3Aportswigger-net-research-crlf-powered-desync-attacks.md)
- Rule/WAF engines with string functions (`concat()`) where `\x0d\x0a` escapes survive into emitted headers [E2](https://bugbountylibrary.com/r/h1%3A1478633.md)
- Config values serialized into INI/TOML/YAML (SMTP password, plugin args) [E3](https://bugbountylibrary.com/r/h1%3A1200647.md)
- HTTP client libraries with special-cased headers (host, content-type) bypassing generic validation [E4](https://bugbountylibrary.com/r/h1%3A1878489.md)[E5](https://bugbountylibrary.com/r/h1%3A1664019.md)

## How to review
Trace every user-controlled value to its sink and confirm newline rejection happens at the sink, not upstream. The invariant: no CR or LF may reach a header value, config line, or directive unless the writer escapes it. Check:
- Is validation applied on the same branch that assigns the value, or only on a generic path? [E4](https://bugbountylibrary.com/r/h1%3A1878489.md)[E5](https://bugbountylibrary.com/r/h1%3A1664019.md)
- Does any decode step (percent, hex, unicode) run after validation? [E1](https://bugbountylibrary.com/r/blog%3Aportswigger-net-research-crlf-powered-desync-attacks.md)[E2](https://bugbountylibrary.com/r/h1%3A1478633.md)
- Are config fields quoted/escaped before serialization? [E3](https://bugbountylibrary.com/r/h1%3A1200647.md)
- In client libraries, does each header field individually run the CRLF check, including special-cased ones? [E4](https://bugbountylibrary.com/r/h1%3A1878489.md)[E5](https://bugbountylibrary.com/r/h1%3A1664019.md)

## Variants seen
- Proxy `$uri` decode enabling request splitting and desync [E1](https://bugbountylibrary.com/r/blog%3Aportswigger-net-research-crlf-powered-desync-attacks.md)
- Edge rule-engine escape sequences injecting Transfer-Encoding [E2](https://bugbountylibrary.com/r/h1%3A1478633.md)
- Config-file injection escalating to RCE via plugin args [E3](https://bugbountylibrary.com/r/h1%3A1200647.md)
- Client library host-header branch skipping CRLF check [E4](https://bugbountylibrary.com/r/h1%3A1878489.md)
- Client library content-type header left unsanitized [E5](https://bugbountylibrary.com/r/h1%3A1664019.md)

## Why fixes fail
Fixing one insertion point leaves others: when double-CRLF splitting is blocked, a single injected Transfer-Encoding still forces desync, and cookies or custom upstream headers remain untested [E1](https://bugbountylibrary.com/r/blog%3Aportswigger-net-research-crlf-powered-desync-attacks.md). Validating generic headers while special-cased ones skip the check leaves the hole open [E4](https://bugbountylibrary.com/r/h1%3A1878489.md)[E5](https://bugbountylibrary.com/r/h1%3A1664019.md). The invariant must hold per-field and per-sink, not once at a shared entry point.

## Impact and severity
High: request smuggling and cache/response-queue poisoning stealing cookies and PII [E1](https://bugbountylibrary.com/r/blog%3Aportswigger-net-research-crlf-powered-desync-attacks.md)[E2](https://bugbountylibrary.com/r/h1%3A1478633.md), RCE [E3](https://bugbountylibrary.com/r/h1%3A1200647.md), header/request splitting in client libraries [E4](https://bugbountylibrary.com/r/h1%3A1878489.md)[E5](https://bugbountylibrary.com/r/h1%3A1664019.md). Worse when the sink sits at a shared edge or controller, multiplying reach across tenants.

## Evidence
- E1: https://bugbountylibrary.com/r/blog%3Aportswigger-net-research-crlf-powered-desync-attacks.md
- E2: https://bugbountylibrary.com/r/h1%3A1478633.md
- E3: https://bugbountylibrary.com/r/h1%3A1200647.md
- E4: https://bugbountylibrary.com/r/h1%3A1878489.md
- E5: https://bugbountylibrary.com/r/h1%3A1664019.md
