What Is CRLF Injection?
CRLF stands for carriage return and line feed, the control characters historically used to terminate lines in HTTP/1.x messages. If untrusted input is inserted into an HTTP header without correct validation, those characters can be interpreted as header separators instead of literal data.
MITRE CWE-113 covers improper neutralization of CR/LF sequences in HTTP headers and includes both request and response splitting contexts.
What Is HTTP Response Splitting?
HTTP response splitting occurs when injected line boundaries cause downstream software to interpret attacker-controlled output as additional response headers or message content. Impact depends on the server, framework, proxy and client behavior.
Modern frameworks often reject newlines in header values, but application code should not assume every custom proxy, library or legacy integration has the same protection.
Secure HTTP Header Construction Pattern
Avoid writing raw HTTP header lines. Use framework APIs and explicitly validate data that will become a header value.
function setDownloadName(response, displayName) {
if (!/^[A-Za-z0-9._ -]{1,120}$/.test(displayName)) {
throw new Error("invalid display name");
}
response.setHeader("X-Download-Name", displayName);
}The allowlist here is an example for a constrained display label. Other header values may need different validation rules; the key principle is that request data must not control raw line boundaries.
Where CRLF Injection Appears
Redirect/location headers
Untrusted redirect values or reflected parameters reach response headers.
Cookies and custom headers
Application values are serialized into Set-Cookie or custom metadata.
Download metadata
User-controlled filenames or labels are inserted into Content-Disposition or related headers.
Logging/protocol bridges
Newline injection can also matter in logs or other line-oriented protocols even when HTTP splitting is not possible.
Security Impact
- Insertion or modification of response headers in vulnerable stacks.
- Cache poisoning or response confusion where intermediaries disagree on message boundaries.
- Cookie manipulation or security-header interference depending on the sink.
- Client-side content injection in specific response-splitting conditions.
- Log injection or downstream parser confusion when newline-delimited records are affected.
CRLF Injection in HTTP/2, HTTP/3 and Protocol Translation
CR and LF are line delimiters in HTTP/1.x, while HTTP/2 and HTTP/3 encode fields using framed binary representations rather than raw header lines. That does not make header validation optional. RFC 9113 explicitly requires HTTP/2 field values containing carriage return or line feed to be treated as malformed.
The protocol boundary matters because many production paths translate between HTTP versions. A client may speak HTTP/2 to a gateway while the gateway forwards HTTP/1.1 to an origin. RFC 9113 specifically warns that failure to validate fields can become exploitable when an intermediary forwards them into HTTP/1.1, where CR/LF regain delimiter semantics.
Validate header values at every component that creates or transforms HTTP fields, and test the real proxy/CDN/gateway chain. “We use HTTP/2 at the edge” is not sufficient evidence that the entire request/response path is protected from newline injection or parser inconsistencies.
CRLF Injection vs HTTP Request Smuggling
These topics are related to HTTP parsing but target different boundaries. CRLF injection begins with unsafe newline characters entering output such as a header. HTTP request smuggling typically exploits inconsistent request framing between front-end and back-end components, such as disagreement over message length.
A system can be safe from response splitting and still be vulnerable to request smuggling, or vice versa. Test and remediate them independently.
Related Ammune reading: API gateway vs reverse proxy and HTTP security header not detected.
CRLF Injection vs Log Forging and Log Injection
CRLF characters can be dangerous outside HTTP headers too. If an application writes untrusted text directly into line-oriented logs, embedded newlines can create misleading entries, split one event into several apparent records or interfere with downstream parsers. That is generally classified as log injection/forging rather than HTTP response splitting.
The fixes overlap at a principle level—do not let external data control record delimiters—but the sinks are different. HTTP fields should be created through framework header APIs that reject invalid field values. Logs should use structured logging or context-appropriate escaping so user-controlled data remains a field value instead of becoming a new log record.
Do not “fix” HTTP header injection by globally stripping CR/LF from every input parameter. Validate according to the destination. A multiline message may be legitimate application data while being completely inappropriate inside a header name, header value or line-oriented audit record.
CRLF Injection vs Request Smuggling vs Log Injection
| Weakness | Boundary being confused | Primary defensive focus |
|---|---|---|
| CRLF / response splitting | Untrusted data becomes an HTTP field/message delimiter | Safe header APIs, field validation, reject CR/LF in HTTP field values |
| HTTP request smuggling | Two HTTP recipients disagree about request boundaries or framing | Consistent parsing/framing across proxy and origin chain |
| Log injection / forging | Untrusted data becomes a log-record delimiter or misleading record content | Structured logging and context-appropriate encoding |
The same raw newline characters can appear in more than one class of bug, but remediation belongs at the destination that interprets them. Avoid global character stripping as a substitute for context-aware output handling.
CRLF Injection Prevention
- Use framework response/header APIs rather than manually serializing HTTP lines.
- Reject CR and LF in data that will become a header value unless the framework provides a documented safe encoding model.
- Validate header values against the narrowest expected format and length.
- Avoid reflecting arbitrary request headers or parameters into response headers.
- Normalize and validate redirect targets, filenames and custom metadata before output.
- Keep web servers, frameworks and proxies patched so built-in header validation remains current.
- Test the full proxy/CDN/load-balancer/application chain because intermediaries may parse edge cases differently.
How to Test CRLF Handling in a Controlled Environment
Use unit tests to verify that header APIs reject newline characters and that application validation fails closed. Integration tests should run through the same reverse proxies and gateways used in production because message handling can differ across layers.
Validation tests can assert that literal and encoded newline characters are rejected or safely handled before raw serialization, then repeat those tests through the same proxy and gateway transformations used in production.
Runtime Visibility Around Header-Injection Probing
Ammune can help identify repeated malformed header/parameter patterns and anomalous HTTP behavior at the API layer. Secure output construction and consistent proxy parsing remain the primary controls.
CRLF / Response Splitting Checklist
- Inventory response headers containing request-derived data.
- Use framework header APIs only.
- Reject newline characters at the correct boundary.
- Validate redirect and filename metadata.
- Test behind the real proxy chain.
- Patch legacy HTTP libraries and components.
- Keep response/header errors out of public detail.
- Monitor for repeated newline/header-injection probes.
Frequently Asked Questions
What is CRLF injection?
It is injection of carriage-return or line-feed characters into line-oriented output such as HTTP headers.
What is HTTP response splitting?
It is a condition where injected boundaries cause a response stream to be interpreted as separate headers or messages.
Is CRLF injection the same as request smuggling?
No. Request smuggling primarily exploits inconsistent request framing between HTTP components.
Do modern frameworks block CRLF injection?
Many do reject newlines in header values, but custom code, legacy libraries and intermediary behavior still require verification.
How should applications prevent CRLF injection?
Use safe header APIs, reject CR/LF in constrained header values and avoid raw HTTP serialization of untrusted input.
Primary References
Protect APIs From Malformed HTTP and Header Abuse
Use safe header construction, consistent proxy behavior and runtime API monitoring to reduce newline, splitting and parser-confusion risk.
