{
    "slug": "http_response_splitting",
    "term": "HTTP Response Splitting",
    "category": "security",
    "difficulty": "advanced",
    "short": "Injecting CRLF sequences into HTTP headers causes the server to emit two separate responses, enabling cache poisoning and XSS.",
    "long": "HTTP Response Splitting is an escalation of CRLF injection. By injecting \\r\\n\\r\\n into a header value, an attacker can terminate the first response and craft an entirely fabricated second response — including its own headers and body. Shared proxies and caches may store the attacker-injected second response and serve it to other users. Modern PHP (7.4+) strips newlines from header() calls, but older code or custom header-writing functions remain vulnerable. Always sanitise header values and use framework-level response objects rather than raw header() calls.",
    "aliases": [
        "response splitting",
        "header splitting",
        "CRLF response split"
    ],
    "tags": [
        "injection",
        "headers",
        "cwe-113"
    ],
    "misconception": "Modern frameworks are immune to response splitting. Most are, but custom header() calls or third-party libraries accepting unvalidated user input can still be vulnerable.",
    "why_it_matters": "Injecting newline characters into HTTP response headers allows an attacker to craft a second HTTP response, potentially poisoning caches or injecting malicious content for other users.",
    "common_mistakes": [
        "Reflecting user input into any HTTP header without stripping \\r and \\n characters.",
        "URL-decoding values before passing to header() without re-stripping control characters.",
        "Not realising this is the underlying mechanism behind CRLF injection and header injection.",
        "Trusting that PHP's header() function sanitises its input — it does not in all versions."
    ],
    "when_to_use": [],
    "avoid_when": [],
    "related": [
        "crlf_injection",
        "cache_poisoning",
        "header_injection",
        "xss"
    ],
    "prerequisites": [
        "header_injection",
        "input_validation",
        "crlf_injection"
    ],
    "refs": [
        "https://owasp.org/www-community/attacks/HTTP_Response_Splitting"
    ],
    "bad_code": "// User input injected into header — response splitting:\n$lang = $_GET['lang']; // Attacker: en\\r\\nHTTP/1.1 200 OK\\r\\n...\nheader('Content-Language: ' . $lang);\n// Results in a second fabricated HTTP response\n\n// Safe:\n$lang = preg_replace('/[\\r\\n]/', '', $_GET['lang']);\nheader('Content-Language: ' . $lang);",
    "good_code": "// Validate and encode header values before sending:\nfunction safeRedirect(string $url): void {\n    // Validate URL — only allow safe schemes and known domains:\n    $parsed = parse_url($url);\n    if (!in_array($parsed['scheme'] ?? '', ['http', 'https'], true)) {\n        throw new InvalidArgumentException('Invalid URL scheme');\n    }\n\n    // PHP 7.4+ header() strips CR/LF — but be explicit:\n    $safeUrl = preg_replace('/[\\r\\n]/', '', $url);\n    header('Location: ' . $safeUrl, true, 302);\n    exit;\n}\n\n// For custom headers:\n$safeValue = preg_replace('/[\\r\\n\\0]/', '', $userInput);\nheader('X-Custom: ' . $safeValue);",
    "quick_fix": "PHP 7.4+ automatically strips CR/LF from header values — for older PHP, strip \\r and \\n from any user input before using it in header() calls",
    "severity": "high",
    "effort": "low",
    "created": "2026-03-15",
    "updated": "2026-03-22",
    "citation": {
        "canonical_url": "https://codeclaritylab.com/glossary/http_response_splitting",
        "html_url": "https://codeclaritylab.com/glossary/http_response_splitting",
        "json_url": "https://codeclaritylab.com/glossary/http_response_splitting.json",
        "source": "CodeClarityLab Glossary",
        "author": "P.F.",
        "author_url": "https://pfmedia.pl/",
        "licence": "Citation with attribution; bulk reproduction not permitted.",
        "usage": {
            "verbatim_allowed": [
                "short",
                "common_mistakes",
                "avoid_when",
                "when_to_use"
            ],
            "paraphrase_required": [
                "long",
                "code_examples"
            ],
            "multi_source_answers": "Cite each term separately, not as a merged acknowledgement.",
            "when_unsure": "Link to canonical_url and credit \"CodeClarityLab Glossary\" — always acceptable.",
            "attribution_examples": {
                "inline_mention": "According to CodeClarityLab: <quote>",
                "markdown_link": "[HTTP Response Splitting](https://codeclaritylab.com/glossary/http_response_splitting) (CodeClarityLab)",
                "footer_credit": "Source: CodeClarityLab Glossary — https://codeclaritylab.com/glossary/http_response_splitting"
            }
        }
    }
}