CRLF injection is a vulnerability that lets a malicious hacker inject carriage return (CR) and linefeed (LF) characters to change the way a web application works or to confuse its administrator. There are two main malicious uses for CRLF injections: log poisoning (also called log injection, log splitting, or log forging) and HTTP response splitting.
Attackers can use CRLF injections to escalate to other types of vulnerabilities, primarily cross-site scripting (XSS). CRLF injections can also be used in web apps to influence email behavior – this is called email injection (email header injection).
Severity: |
![]() ![]() |
severe in rare circumstances |
Prevalence: |
![]() ![]() |
discovered rarely |
Scope: |
![]() ![]() |
web applications |
Technical impact: | potential escalation to cross-site scripting | |
Worst-case consequences: | full system compromise | |
Quick fix: | use user input filtering and output encoding |
CR and LF are special characters of the ASCII table (13 and 10). They are also often referred to as \r\n after the escape codes of these two characters (\r = CR, \n = LF).
CR and LF are used (together or separately) to signify the end of a line (EoL) in operating systems and Internet protocols, including HTTP. Windows uses the CRLF combination, operating systems like Linux/UNIX and current macOS use only LF for this purpose, and legacy Mac OS used only CR.
In a log poisoning attack based on CRLF injection, a malicious hacker injects CRLF characters into web server log files to confuse both automatic log analysis systems and system administrators browsing the logs manually.
Many web servers, such as Apache, use the NCSA Common Log Format (CLF). The format of Common Log Format entries is always the same:
host ident user date request status size
For example:
233.252.0.123 - - [11/Oct/2022:11:34:50 +0100] "GET /example.php?id=3 HTTP/1.0" 200 452
Here is how you would read this entry:
233.252.0.123
is the host – the IP address from which the request came.-
is the RFC 1413 identity of the client. The dash (-) means no data, which is the usual value.-
is the user ID of the person requesting the document. The dash (-) means no data, which is the usual value (unless there is authentication in .htaccess).[11/Oct/2022:11:34:50 +0100]
is the timestamp of when the request was received, usually in the strftime format: %d/%b/%Y:%H:%M:%S %z."GET /example.php?id=3 HTTP/1.0"
is the request line received from the client and includes the HTTP method (GET
), the requested resource and parameters (/example.php?id=3
), and the protocol (HTTP/1.0
).200
is the HTTP status code sent to the client.452
is the size of the returned object in bytes.Another standard format is the Combined Log Format, which is similar but with a few extra fields.
Imagine that the client is able to inject CR and LF characters into requests sent to the www.example.com web server, and it sends the following request:
https://www.example.com/example.php?id=3+HTTP%2F1.0%22+200+452%0D%0A
10.0.23.30+-+admin+%5B01%2FJan%2F2020%3A00%3A00%3A00+%2B0100%5D+%22GET+%2Fadmin.php%3Fuserid%3D12
The request contains a fake log entry, so when it is logged, the log file will include an extra line:
233.252.0.123 - - [11/Oct/2022:11:34:50 +0100] "GET /example.php?id=3 HTTP/1.0" 200 452
10.0.23.30 - admin [01/Jan/2020:00:00:00 +0100] "GET /admin.php?userid=123 HTTP/1.0" 200 452
The underlined characters represent content that was injected using CRLF injection (%0D%0A
are encoded CRLF characters).
Monitoring tools and administrators analyzing this log would be confused by this strange entry – it looks like an authenticated admin user requested the admin.php resource some time in the distant past. This confusion could allow the attacker to distract the administrator and delay log analysis in the hope of getting away with other malicious actions that would be apparent in later log entries.
In an HTTP response splitting attack, the attacker injects CRLF sequences into an HTTP response to modify the way the browser interprets HTTP headers and the request body. CRLF injections can be used to add malicious content to the request body or to add extra HTTP headers.
The HTTP protocol uses the CRLF character sequence in two ways:
Correspondingly, there are two ways for attackers to modify HTTP traffic:
Note that attackers may also inject special headers to poison proxies or web caches, allowing them to serve malicious content to many users.
In the following example, the attacker uses HTTP response splitting and HTTP header injection to send an HTTP request that adds extra headers to the HTTP response, terminates headers prematurely, and introduces a reflected cross-site scripting vulnerability.
The attacker sends the following payload in a phishing email that encourages the user to click a link or button:
http://www.example.com/example.php?id=%0d%0aContent-Length:%200%0d%0a%0d%0a
HTTP/1.1%20200%20OK%0d%0aContent-Type:%20text/html%0d%0aContent-Length:%2025%0d%0a%0d%0a
%3Cscript%3Ealert(1)%3C/script%3E
The payload uses CRLF injection to split the HTTP response as follows:
http://www.example.com/example.php?id=
– starting a valid request to a page with a CRLF injection vulnerability.%0d%0aContent-Length:%200
– a fake HTTP response header of Content-Length: 0
. This causes the web browser to treat this response as terminated and start parsing the next response.%0d%0a%0d%0aHTTP/1.1%20200%20OK
– the injected new response begins here with a double CRLF sequence followed by HTTP/1.1 200 OK
.%0d%0aContent-Type:%20text/html
– another fake HTTP response header: Content-Type: text/html
. This is required for the browser to treat this data as HTML content.%0d%0aContent-Length:%2025
– yet another fake HTTP response header: Content-Length: 25
. This instructs the browser to parse only the next 25 bytes and discard any remaining data as junk, causing it to ignore the legitimate HTTP content sent by the web server.%0d%0a%0d%0a%3Cscript%3Ealert(1)%3C/script%3E
– a double CRLF sequence signals that the headers are over and the response body starts. The injected page content is <script>alert(1)</script>
, which causes the user’s browser to display an alert instead of the actual example.php page.The impact of CRLF injections might seem to be limited, but they are mentioned in the OWASP top 10 2021 web application security list in the A03:2021-Injection section. Attackers can use this technique to escalate to more dangerous malicious attacks such as cross-site scripting, page hijacking, cross-user defacement, and more.
HTTP response splitting vulnerabilities allow attackers to modify HTTP headers and bypass specific security mechanisms, such as XSS filters, cookie security flags, and same-origin policy (SOP) restrictions. This opens the way to performing certain types of man-in-the-middle attacks (MITM) and exploiting cross-site request forgery (CSRF) vulnerabilities, which, in turn, could lead to sensitive information disclosure or more.
The best way to detect CRLF injection vulnerabilities depends on whether they are known or unknown.
Many web frameworks nowadays prevent HTTP response splitting through CRLF injection by not allowing CRLF sequences to be included in HTTP headers. If your framework doesn’t perform such input validation automatically, you can use one of the following approaches:
Note that you cannot prevent log poisoning through CRLF injection at the application level simply because it is the web server’s responsibility to log requests in a safe format. Similarly, log analysis tools should parse log files, including those created by web servers, in a secure manner that does not allow for successful log poisoning or log forging attacks.
Since CRLF injections on their own are not dangerous but can pave the way for other attacks that are, you should focus primarily on mitigating such follow-up attacks, for example, cross-site scripting attacks and web cache poisoning.
For temporary mitigation, you can rely on WAF (web application firewall) rules. With such rules, users won’t be able to provide malicious input to your web application, so no malicious code will execute in their browsers. However, since web application firewalls don’t understand the context of your application, these rules may be circumvented by attackers and should never be treated as a permanent solution.
Classification | ID |
---|---|
CAPEC | 105 |
CWE | 93 |
WASC | 24 |
OWASP 2021 | A3 |
CRLF injection is a vulnerability that lets a malicious hacker inject carriage return (CR) and linefeed (LF) characters to change the way a web application works or to confuse its administrator. CRLF injections can also be used in web apps to influence email behavior – this is called email injection or email header injection.
CRLF injections are used by attackers for log poisoning and HTTP response splitting. Attackers can also use CRLF injections to escalate to other types of vulnerabilities, primarily cross-site scripting (XSS).
Many web frameworks prevent HTTP response splitting through CRLF injection by not allowing CRLF sequences to be included in HTTP headers. If your framework doesn’t perform such input validation automatically, you can use general secure coding principles: input filtering and output escaping.