# HTTP Response Splitting Attacks

#### Tools recognizing this:

<kbd>Fortify</kbd> <kbd>Checkmarx</kbd> <kbd>SonarQube</kbd> <kbd>Snyk</kbd> <kbd>Semgrep</kbd> <kbd>CodeQL</kbd>

## What is HTTP Response Splitting and How Does it Work?

HTTP Response Splitting is a web security vulnerability that occurs when an attacker can inject newline characters (CR/LF) into response headers. This allows the attacker to split the response into multiple responses, potentially leading to:

* Cache poisoning attacks
* Cross-site scripting (XSS)
* Page defacement
* Response header manipulation
* Session hijacking

This guide covers HTTP Response Splitting attacks, examples, prevention methods, and how to protect your applications using real-world techniques.

## One Simple HTTP Response Splitting Attack Example

Consider this example of setting a cookie with user input:

{% code overflow="wrap" %}

```
response.setHeader("Location", userInput + "/index.html");
```

{% endcode %}

An attacker could provide this input:

<mark style="color:red;">`/page.html\r\nSet-Cookie: sessionId=hijacked`</mark>

The resulting response headers become:

<kbd>Location: /page.html</kbd> <kbd><mark style="color:red;">Set-Cookie: sessionId=hijacked<mark style="color:red;"></kbd>

This allows the attacker to inject their own response headers, potentially hijacking user sessions or performing other malicious actions.

## HTTP Response Splitting Prevention Methods: How to Fix Your Code

The most effective way to fix HTTP Response Splitting is to properly validate and sanitize any user input that goes into response headers. This includes removing or encoding CR/LF characters and validating the input against an allowlist of acceptable values.

### Code Samples

{% tabs %}
{% tab title="Java" %}
**Vulnerable Code**

<pre class="language-java"><code class="lang-java">String userInput = request.getParameter("page");
response.setHeader("Location", <a data-footnote-ref href="#user-content-fn-1">userInput + "/index.html"</a>);
</code></pre>

**Fixed Code**

```java
String userInput = request.getParameter("page");
String sanitizedInput = userInput.replaceAll("[\r\n]", "");
response.setHeader("Location", sanitizedInput + "/index.html");
```

**Fix Explanation**

The vulnerable code directly includes user input in response headers. The fix removes all CR/LF characters from the input using replaceAll(). This prevents attackers from splitting the response with injected newlines.
{% endtab %}

{% tab title="Python" %}
**Vulnerable Code**

```python
user_input = request.args.get('redirect')
response.headers['Location'] = user_input + '/index.html'
```

**Fixed Code**

```python
import re
user_input = request.args.get('redirect')
sanitized_input = re.sub(r'[\r\n]', '', user_input)
response.headers['Location'] = sanitized_input + '/index.html'
```

**Fix Explanation**

The vulnerable code directly uses user input in response headers. The fix uses regex to remove all CR/LF characters from the input. The sanitized input is safe to use in response headers.
{% endtab %}

{% tab title="C#" %}
**Vulnerable Code**

```csharp
string userInput = Request.QueryString["redirect"];
Response.AddHeader("Location", userInput + "/index.html");
```

**Fixed Code**

```csharp
string userInput = Request.QueryString["redirect"];
string sanitizedInput = Regex.Replace(userInput, @"[\r\n]", "");
Response.AddHeader("Location", sanitizedInput + "/index.html");
```

**Fix Explanation**

The vulnerable code includes raw user input in response headers. The fix uses Regex.Replace to remove CR/LF characters. The sanitized input prevents response splitting attacks.
{% endtab %}

{% tab title="PHP" %}
**Vulnerable Code**

```php
$userInput = $_GET['redirect'];
header("Location: " . $userInput . "/index.html");
```

**Fixed Code**

```php
$userInput = $_GET['redirect'];
$sanitizedInput = str_replace(array("\r", "\n"), "", $userInput);
header("Location: " . $sanitizedInput . "/index.html");
```

**Fix Explanation**

The vulnerable code directly concatenates user input into headers. The fix removes CR/LF characters using str\_replace. The sanitized input is safe for use in HTTP headers.
{% endtab %}

{% tab title="Node.js" %}
**Vulnerable Code**

```javascript
const userInput = req.query.redirect;
res.setHeader('Location', userInput + '/index.html');
```

**Fixed Code**

```javascript
const userInput = req.query.redirect;
const sanitizedInput = userInput.replace(/[\r\n]/g, '');
res.setHeader('Location', sanitizedInput + '/index.html');
```

**Fix Explanation**

The vulnerable code uses unvalidated user input in headers. The fix removes CR/LF characters using regular expressions. The sanitized input prevents response splitting attacks.
{% endtab %}
{% endtabs %}

## Need more help in preventing HTTP Response Splitting?

[Mobb](https://mobb.ai) supports fixing many forms of HTTP Response Splitting vulnerabilities, and can mitigate your issues in batch.

Start now for free at [app.mobb.ai](https://app.mobb.ai)

### We'd love your feedback!

We're excited to hear your thoughts and ideas about fixing vulnerabilities.

[Book a meeting](https://calendly.com/mobbai/demo) or [Contact us](https://content.mobb.ai/contact) if you have any corrections, questions or suggestions. Start now for free at <https://app.mobb.ai>

[^1]: This is the vulnerable part


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.mobb.ai/mobb-user-docs/fixing-guides/http-response-splitting-fix-guide.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
