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=trueresults inSet-Cookie: admin=trueheader in HTTP response - Raw HTTP response shows double CRLF (
\r\n\r\n) followed by attacker-controlled HTML:
- Scanner's proxy logs show injected
Location: http://evil.comheader - Parameter
?url=valid%0aX-Injected:%20maliciousadds 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\ncharacters
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.