CRLF injection, HTTP response splitting, and HTTP header injection vulnerabilities

This article explains what the CRLF injection is and how it can be used to do HTTP response splitting or HTTP header injection to trick the victim’s browser.

This is an archive post from the Netsparker (now Invicti) blog. Please note that the content may not reflect current product names and features in the Invicti offering.

What is the CRLF combination?

Whenever a browser sends a request to a web server, the web server answers back with a response containing both the HTTP response headers and the actual website content, i.e. the response body. The HTTP headers and the HTML response (website content) are separated by a specific combination of special characters, namely a carriage return (CR) and a line feed (LF). For short, they are also known as CR/LF or simply CRLF.

The web server uses the CRLF combination to understand when new HTTP header begins and another one ends. The CRLF can also tell a web application or user that a new line begins in a file or in a text block. The CRLF characters are a standard HTTP/1.1 message, so they are used by all web servers, including Apache, Microsoft IIS, and others.

What is the CRLF injection vulnerability?

In a CRLF injection attack, the attacker inserts the carriage return and linefeed characters into user input to trick the server, the web application, or the user into thinking that an object has terminated and another one has started. While CRLF sequences are not malicious characters in themselves, they can be used with malicious intent, for  example for HTTP response splitting.

CRLF injection in web applications

In web applications, a CRLF injection can have a severe impact, depending on what the application does with the request blocks. Consequences can range from information disclosure to code execution, a direct impact web application security vulnerability. In fact, a CRLF injection attack can have very serious repercussions on a web application, even though it was never listed in the OWASP Top 10 list. Let's look at an example that shows how to use CRLF injection to manipulate log files in an admin panel.

Example: CRLF injection in a log file

Imagine a log file in an admin panel with the output stream pattern of IP - Time - Visited Path, such as the below:

123.123.123.123 - 08:15 - /index.php?page=home

If an attacker is able to inject the CRLF characters into the HTTP request, they can change the output stream and fake log entries. The response from the web application can be changed to something like this:

/index.php?page=home&%0d%0a127.0.0.1 - 08:15 - /index.php?page=home&restrictedaction=edit

The %0d and %0a are URL-encoded forms of CR and LF. Therefore, the log entries would look like this after the attacker inserted those characters and the application displays them (IP - Time - Visited Path):

123.123.123.123 - 08:15 - /index.php?page=home&
127.0.0.1 - 08:15 - /index.php?page=home&restrictedaction=edit

By exploiting a CRLF injection vulnerability, attackers can fake entries in the log file to obfuscate their actions. In this case, the attacker is literally doing page hijacking and modifying the response.

Imagine a scenario where the attacker has the admin password and uses the restrictedaction parameter, which can only be used by an admin. If an administrator notices that an unknown IP has used the restrictedaction parameter, they may suspect malicious activity. However, since now it looks like the command was issued by the localhost (and therefore probably by someone who has access to the server, like an admin), it does not look suspicious.

The whole part of the query beginning with %0d%0a will be handled by the server as one parameter. After that, there is another & character with the parameter restrictedaction, which will be parsed by the server as another parameter. Effectively, this would be the same query as:

/index.php?page=home&restrictedaction=edit

HTTP response splitting

Since the header and body of an HTTP response are separated by CRLF characters, an attacker can try to inject those. A combination of CRLFCRLF will tell the browser that the header ends and the body begins. This could allow an attacker to write data into the response body where the HTML code is sent, leading to a cross-site scripting  (XSS) vulnerability.

Example: HTTP response splitting leading to XSS

Imagine an application that sets a custom header, for example:

X-Your-Name: Bob

The value of the header is set via a GET parameter called name. If no URL-encoding is in place and the value is directly reflected inside the header, it might be possible for an attacker to insert the above mentioned combination of CRLFCRLF to tell the browser where the request body begins. That way, attackers may be able to insert data such as a XSS payload, for example:

?name=Bob%0d%0a%0d%0a<script>alert(document.domain)</script>

The above will display an alert window in the context of the attacked domain.

HTTP header injection

By exploiting a CRLF injection, an attacker can also insert HTTP headers which could be used to defeat security mechanisms such as a browser's XSS filter or the same-origin-policy. This allows malicious actors to obtain sensitive information like CSRF tokens. Attackers can also set cookies which could be exploited by logging the victim into the attacker's account or used to exploit otherwise unexploitable cross-site scripting vulnerabilities.

HTTP header injection can also be used to extract sensitive data. If an attacker is able to inject HTTP headers that activate CORS (cross-origin resource sharing), this will enable them to get JavaScript access to resources that are otherwise protected by SOP (same-origin policy) which prevents access between sites with different origins.

Impacts of the CRLF injection vulnerability

The impact of CRLF injections varies depending on the attack context, but will typically cover all the consequences of cross-site scripting and information disclosure that the injection allowed. The technique can also be used to deactivate certain security restrictions like XSS filters and same-origin policy in the victim's browser, paving the way for other malicious attacks.

How to prevent CRLF and HTTP header injection in web applications

The best prevention method is to avoid using user input directly in response headers. If that is not possible, you should always use a function to encode the CRLF special characters. Another web application security best practice is to use up-to-date programming languages and libraries that will not allow CR and LF to be injected inside functions that set HTTP headers.

Vulnerability classification and severity table

Classification ID / Severity
PCI v3.2 6.5.1
OWASP 2013 A1
OWASP 2017 A1
CWE 93
CAPEC 105
WASC 24
HIPAA 164.306(a), 164.308(a)
ISO27001 A.14.2.5
CVSS:3.0
CVSS:3.0: AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:H
Netsparker Medium
Zbigniew Banach

About the Author

Zbigniew Banach - Sr Technical Content Writer

Technical Content Writer at Invicti. Drawing on his experience as an IT journalist and technical translator, he does his best to bring web application security and cybersecurity in general to a wider audience.