Skip to content

CWE-113: HTTP Response Splitting

Overview

This guidance helps interpret DAST findings for CWE-113: HTTP Response Splitting (CRLF Injection). During dynamic scanning, the scanner detected that user-controlled input influenced HTTP response headers, allowing injection of additional headers or response bodies via CRLF (\r\n) characters.

What the DAST scanner detected:

  • CRLF sequences (%0d%0a, \r\n, %0a, %0d) in input parameters reflected into HTTP response headers
  • Injected headers appearing in HTTP responses (e.g., Set-Cookie, Content-Type, Location)
  • Split responses: Scanner received multiple HTTP responses from a single request, or saw injected HTML/JavaScript in response bodies
  • Cache poisoning: Intermediate caches stored manipulated responses
  • Header injection confirmation: Raw HTTP response analysis showing attacker-controlled header names/values

Key DAST evidence:

  • Input ?redirect=test%0d%0aSet-Cookie:%20admin=true results in Set-Cookie: admin=true header in HTTP response
  • Raw HTTP response shows double CRLF (\r\n\r\n) followed by attacker-controlled HTML:
    HTTP/1.1 302 Found
    Location: /page%0d%0a%0d%0a<script>alert(1)</script>
    
    <script>alert(1)</script>
    
  • Scanner's proxy logs show injected Location: http://evil.com header
  • Parameter ?url=valid%0aX-Injected:%20malicious adds custom header to response

Analyzing the Dynamic Scan Result

What the DAST Scanner Found

When reviewing your security scan results, you'll see:

HTTP Request Details

  • URL and endpoint that triggered the finding
  • HTTP method (GET, POST, etc.)
  • Query parameters or form data with test payloads
  • Request headers and body content

HTTP Response Evidence

  • Response showing the vulnerability manifestation
  • Evidence of improper handling or injection
  • Runtime behavior indicators

Attack Vector

  • Which parameter or input is vulnerable
  • Type of exploitation possible
  • Context where the vulnerability appears

Mapping DAST Findings to Source Code

Find the Vulnerable Endpoint

Use the HTTP request URL to locate the code:

# Search for the URL path in your codebase
grep -r "/redirect" src/
grep -r "/setcookie" src/
grep -r "/download" src/
grep -r "route.*redirect" src/

Locate the Route Handler

Common patterns to search for:

  • Python Flask/Django: @app.route('/redirect'), redirect() with user input
  • Node.js Express: app.get('/redirect', ...), res.redirect(), res.setHeader()
  • Java Spring: @GetMapping("/redirect"), header manipulation
  • ASP.NET: [Route("redirect")], Response.AddHeader()
  • PHP: header() function with user input

Find the Parameter Handling

Search for parameters used in headers:

# Find where the parameter is accessed
grep -r "request.args.get('url')" src/       # Python Flask
grep -r "req.query.redirect" src/            # Node.js
grep -r "@RequestParam.*location" src/       # Java Spring
grep -r "Request.QueryString['url']" src/    # ASP.NET
grep -r "$_GET['redirect']" src/             # PHP

Trace to Vulnerable Operation

Look for where user input is used in:

  • HTTP headers: Location, Set-Cookie, Content-Type, custom headers
  • Redirect functions: Passing unsanitized input to redirect
  • Cookie setting: Cookie name or value from user input
  • CRLF injection points: Any header construction with user data
  • Missing CRLF handling / unsafe header construction: No removal of \r\n characters

Remediation

Core principle: Never allow untrusted input to influence HTTP response headers; header values must be validated or constructed by the server so they cannot introduce CRLF characters or alter response structure.

→ For comprehensive remediation guidance, see Static CWE-113 Guidance

Language-Specific Guidance

The static guidance provides detailed remediation steps for many languages. If you need language-specific examples:

Verification and Follow-Up Testing

After applying the fix:

Reproduce the Vulnerability

# Use curl to test CRLF injection
curl -I "http://localhost:3000/redirect?url=test%0d%0aSet-Cookie:%20admin=true"
curl -I "http://localhost:3000/download?file=report.pdf%0d%0aContent-Type:%20text/html"

# Or use browser DevTools Network tab

Verify the Fix

  • Confirm untrusted input is never used directly in response headers, or is strictly validated using framework-provided header APIs that reject CRLF
  • Verify framework's built-in header validation is used
  • Check that injected headers don't appear in response
  • Ensure URL encoding is properly handled

Test Edge Cases

# CRLF injection attempts
/redirect?url=test%0d%0aSet-Cookie:%20session=attacker
/redirect?url=test%0aSet-Cookie:%20admin=true
/redirect?url=test%0d%0a%0d%0a<script>alert(1)</script>

# Header injection
/setcookie?name=session%0d%0aSet-Cookie:%20admin=true

# Cache poisoning
/redirect?url=%0d%0aContent-Length:%200%0d%0a%0d%0aHTTP/1.1%20200%20OK

# Or use browser DevTools Network tab to copy as cURL

Re-run DAST Scanner

Run your dynamic scanner again on the fixed endpoint to confirm remediation.

Additional Resources