Skip to content

CWE-93: CRLF Injection

Overview

CRLF Injection occurs when untrusted user input is included in HTTP headers or other protocol fields without proper validation or encoding, allowing attackers to inject carriage return (CR) and line feed (LF) characters to manipulate protocol behavior.

OWASP Classification

A05:2025 - Injection

Risk

High: Attackers can perform HTTP response splitting, set malicious headers, or inject content into responses, leading to XSS, cache poisoning, or session fixation.

Remediation Steps

Core principle: Never allow untrusted data to inject CRLF or protocol delimiters; validate/encode before generating structured text (headers, logs, protocols).

Trace the Data Path and Locate the Vulnerability

Analyze how untrusted data reaches HTTP header construction:

  • Review the flaw details to identify the specific file, line number, and code pattern
  • Source: Where untrusted data enters (user input, external file, database, network request)
  • Sink: HTTP header setting functions (response.headers[], setHeader(), addHeader())
  • String concatenation: Look for untrusted data being directly inserted into header values
  • Understand the data flow from source to sink

Encode or Remove CR/LF Characters (Primary Defense)

Sanitize all untrusted data before using it in HTTP headers:

  • Remove or encode carriage return (\r) and line feed (\n) characters
  • Use replace() or regex to strip CR/LF: user_input.replace('\r', '').replace('\n', '')
  • Also consider removing tab (\t) and null byte (\0) characters
  • Apply sanitization before any header manipulation
  • Follow the secure code examples provided in language-specific guidance

Use Framework Security Features

Leverage built-in framework protections:

  • Prefer frameworks that automatically encode or validate headers
  • Use framework APIs that handle header construction safely
  • Avoid manual header construction with string concatenation
  • Use typed header objects when available (e.g., Response objects)
  • Let the framework handle encoding of special characters

Validate Input for Protocol Fields (Defense in Depth)

Add input validation as an additional security layer:

  • Enforce strict type, length, and format checks on all untrusted header values
  • Validate expected patterns (URLs, tokens, content types)
  • Use allowlists for enumerated values (e.g., redirect destinations)
  • Reject or sanitize unexpected characters
  • Implement length limits to prevent header overflow

Monitor and Test

Verify your fixes and enable detection:

  • Test with CRLF injection payloads: %0d%0aSet-Cookie:admin=true, \r\nLocation:http://evil.com
  • Test header splitting: value\r\nX-Injected-Header:malicious
  • Test response splitting: \r\n\r\n<script>alert(1)</script>
  • Log all header values and alert on suspicious patterns
  • Verify the specific input that triggered the finding no longer causes the vulnerability
  • Ensure legitimate functionality still works correctly (e.g., redirects)
  • Re-scan with the security scanner to confirm the issue is resolved

Common Vulnerable Patterns

  • Directly inserting untrusted data into HTTP headers
  • Failing to validate or encode header values

Unsanitized User Input in HTTP Header (Pseudocode)

# Dangerous: user input in header
response.headers['Location'] = user_input

Secure Patterns

CRLF Sanitization for HTTP Headers (Pseudocode)

# Safe: remove CR/LF from input
clean_input = user_input.replace('\r', '').replace('\n', '')
response.headers['Location'] = clean_input

Why this works:

  • Removes carriage return (\r) and line feed (\n) characters that terminate HTTP headers
  • Prevents attackers from injecting additional headers or response body content
  • Blocks HTTP response splitting attacks that enable XSS, cache poisoning, or session fixation
  • Ensures user input cannot break out of the intended header value context
  • Combined with proper URL validation, prevents malicious redirects with injected headers

Language-Specific Guidance

For detailed, framework-specific code examples and patterns, see:

  • Python - Flask, Django, FastAPI examples with CRLF sanitization
  • Java - Spring Boot, Servlets with header validation
  • JavaScript/Node.js - Express, Koa, Next.js with URL and header sanitization
  • C# - ASP.NET Core with header security

Additional Resources