HTTP Response Splitting occurs when an attacker can inject special characters (such as CR and LF characters, represented as %0D%0A in URL encoding) into HTTP headers returned by the web application. These characters can create new, unexpected headers or even an entirely new HTTP response, allowing the attacker to manipulate how browsers or proxies interpret the response.
An HTTP response typically looks like this:
HTTP/1.1 200 OK Content-Type: text/html Set-Cookie: session=12345 Cache-Control: no-cache <!DOCTYPE html> <html>...
Each response contains:
To effectively demonstrate HTTP Response Splitting, you would need:
For this demo, we'll simulate the server behavior using client-side JavaScript to show what would happen.
Note: Modern web frameworks and servers implement controls that make HTTP Response Splitting difficult, but understanding the vulnerability remains important.
This demo shows how an attacker can inject new headers through the Location header in a redirect response.
The browser would redirect to: home.html
Try these malicious inputs in the redirect field:
home.html%0D%0ASet-Cookie:%20stolen=yes
- Injects a cookiehome.html%0D%0AContent-Type:%20text/html%0D%0A%0D%0A<script>alert('XSS')</script>
- Creates a completely new response with XSSIn a vulnerable application, the server might construct a redirect header like this:
// VULNERABLE PHP CODE
$page = $_GET['page'];
header("Location: " . $page);
If the attacker provides page=home.html%0D%0ASet-Cookie:%20stolen=yes
, the server would send:
Location: home.html
Set-Cookie: stolen=yes
This demo shows how HTTP Response Splitting can lead to cache poisoning attacks, where a malicious response is cached and served to multiple users.
The proxy would cache this response for all users requesting product 12345
For example, using this payload:
12345%0D%0AContent-Length:%200%0D%0A%0D%0AHTTP/1.1%20200%20OK%0D%0AContent-Type:%20text/html%0D%0ALast-Modified:%20Mon,%2027%20Oct%202008%2014:50:18%20GMT%0D%0AContent-Length:%2035%0D%0A%0D%0A<script>alert('Cache%20Poisoned')</script>
This would create an initial empty response followed by a completely new response that would be cached and served to all users.
This tab demonstrates various techniques to prevent HTTP Response Splitting vulnerabilities.
// Validate input allows only expected characters
function validateRedirectUrl($url) {
if (preg_match('/^[a-zA-Z0-9\/_.-]+$/', $url)) {
return $url;
}
return 'default.html'; // Default safe value
}
$page = validateRedirectUrl($_GET['page']);
header("Location: " . $page);
// Encode CR and LF characters
function encodeHeaderValue($value) {
return str_replace(["\r", "\n", "%0D", "%0A", "%0d", "%0a"], '', $value);
}
$lang = encodeHeaderValue($_GET['lang']);
header("Set-Cookie: language=" . $lang);
// Modern PHP using a framework's cookie API
// Laravel example
return redirect()->route('home')
->cookie('language', $request->input('lang'), 60);
// Node.js Express example
res.cookie('language', req.query.lang).redirect('/home');
// Add security headers that disable caching for sensitive pages
header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
header("Pragma: no-cache");
header("Expires: 0");
// Use established libraries for URL manipulations
$page = filter_input(INPUT_GET, 'page', FILTER_SANITIZE_URL);
header("Location: " . $page);
// Java example
String sanitizedValue = Encode.forUriComponent(request.getParameter("page"));
response.sendRedirect(sanitizedValue);
Modern web frameworks provide safe methods for setting headers and cookies:
response()->header()
, cookie()
methodsres.set()
, res.cookie()
methodsHttpServletResponse
methods with built-in safetyHttpResponse
objects and their methodsAlways validate and sanitize user input before using it in headers:
// PHP example $page = preg_replace('/[\r\n]/', '', $_GET['page']); header("Location: " . $page); // JavaScript example const userInput = userValue.replace(/[\r\n]/g, ''); response.setHeader("X-User-Input", userInput);
Implement Content Security Policy headers to mitigate the impact of successful attacks:
Content-Security-Policy: default-src 'self'; script-src 'self';
Modern web servers and application frameworks have built-in protections against HTTP Response Splitting. Always keep your software updated to benefit from these security improvements.
Regularly test your applications for HTTP Response Splitting vulnerabilities: