From the course: Secure Development, Programming, and Coding with Veracode
CRLF injection tutorial
From the course: Secure Development, Programming, and Coding with Veracode
CRLF injection tutorial
- [Kevin] Appsec tutorials. CRLF injection. About this course. CRLF injection is a form of application security vulnerability in a family of injection flaws. The presence of CRLF injection in an application's code can potentially allow malicious users to transform data streams in a variety of harmful ways. In this course, you'll see an example of how this weakness could be exploited and then how it can be fixed. At the end of this course, you will understand the risks associated with the CRLF injection and be able to defend against instances of this flaw. To get the most out of this course, if you haven't already done so, we recommend that you take our Introduction to Web Application Security course first. The following video shows how an attacker might discover and exploit a CRLF injection attack. Hello, my name is Kevin Richard and I'm a security researcher with VeriCode. Today I'd like to provide a brief demonstration of the application security weakness known as CRLF injection. To do so, I'm going to use an application called Veri-Insecure, a web app we're building to demonstrate a number of real security vulnerabilities. Let's get started. You may be wondering, in the name CRLF injection, what does the CRLF mean? These letters stand for two uni-code control characters, respectively called Carriage Return and Line Feed. Control characters are units of information that do not represent a written symbol, but instead alter a data stream in other ways. The CRLF, or Carriage Return followed by a Line Feed, is how many platforms represent line break syntax. So within a stream of data, a CRLF is just like pressing enter or return on your keyboard. Now ask yourself what could happen during data processing if an application's users discovered they had the ability to submit CRLFs in unexpected places. Let's see a quick example. Have a look at the page on my screen. We have a simple login page that behaves like any other. Given a correct user name and password, the application will authenticate the user and direct them to another page. But whether or not the credentials are valid, each press of this button makes the application log a record of the attempted access. Investigators use logs like these in the event of a breach to discover which resources were accessed and which systems were affected, but also, what parties were involved. An attacker who tried to infiltrate this site would presume that such a log was kept, and expecting their breach to be detected in time, they grasped that this log would contain evidence of their wrongdoing. So an early step of their plan becomes misdirecting the forthcoming investigation toward some other suspect through populating the log file with false information. We already know that the individual lines of this file are separated by CRLFs. So if a user can inject CRLFs into the data being written, they can force parts of the data onto new lines, and if they can format it correctly, they can make it look like it was written by the application itself. So why not write data to the logs that implicates an innocent party in your hack? Let's plan out our incident. The attacker has to know what a valid log entry actually looks like as well as a failed one. Fortunately in a poorly made app like Veri-Insecure, it's very possible to obtain this information through underhanded means. Watch our Appsec tutorial on directory traversal if you'd like to see one way to do this. The attacker starts with read only access to a sample log file. We extract from this a success and a failure in order to inspect their contents. Admin and scapegoat are present because two users have typed those names. Any user name will appear at the end of a line like this, followed by a CRLF to separate it from the next line. But since the application doesn't remove extra CRLFs when the user submits them, we can manipulate this oversight to make it appear that the user named scapegoat has logged in right before our own attempt has failed. Here's how we do that. Let's start with the back login. As we've observed, these three lines are logged each time a failed login occurs, with only one deviation: the name of the user that tried to log in. Since we can type anything we want inside the form field, we control the data within this bounded space. First we add to the name scapegoat, the user who we wish to frame. Next, we add the line that reports a successful login for scapegoat. Below, there are still two lines that reflect a failed login. For these to make sense in context, we must add back the text from the first line with the user name set to a different account. Now it looks as though these two login attempts happened sequentially. Next we need to replace the line breaks with CRLFs. The CRLF and coding in my editor may not be the same as the one that the application expects, so this is necessary for the line breaks to appear. Finally, we'll URL encode the entire string, because the request specifies a content type that requires this encoding for post data. We now have our payload, the data that we'll submit to the server. Let's submit this entire string in the user name field and see what happens. At first nothing different seems to have happened, which is as we'd expect. However, let's show you what the log file now looks like. Because we copied the formatting of the log file exactly, it now appears that the user scapegoat logged into the application at the time of our breach, an effect made possible by CRLF injection vulnerability. If it later came to light that attackers had interfered with the log and added even one fake entry to it, the entire integrity of that log would be compromised, because there would be no way to guarantee that any given entry was legitimate, nor could one distinguish good entries from bad with 100 percent certainty. The effects of CRLF injection are not simply limited to log injection. CRLF injection, like most injections, is a means to an end, and anytime an attacker is able to insert line delineators into a data stream, it's important to understand the risk that it could create within that context. For example, if you're watching this video, it's possible that you've encountered a different kind of CRLF-related flaw, such as HTTP response splitting. In that scenario, an attacker could set arbitrary headers, take control of a response body, or break a response into two or more separate responses, all because HTTP separates headers, sections, and requests using CRLFs. Though the target is not the same, the root cause of that vulnerability is the same, the failure to neutralize CRLFs within client data. In summary, if an attacker is allowed to insert unwanted CRLFs into a data stream, it may be possible to misuse this ability in a variety of ways. To learn more about different kinds of payloads and attacks, as well as steps for remediation, please continue to watch our training videos or participate in our training courses. This is Kevin Richard from VeriCode. Thank you very much for watching. If a valid CRLF injection flaw has been detected in your application, the next step is to update your code in order to remediate it. Click on any tab to see how to secure your code from the threat of CRLF injection. Hello, again. This is Kevin Richard, security researcher with VeriCode and you've been watching our Appsec tutorial on CRLF injection. In our last video, we showed the sort of circumstances in which an attacker might discover and misuse this vulnerability. Now that you've gained a basic understanding of this issue, let's demonstrate how to fix it. Fortunately, this will be a quick one. First, let's bring up the code from our previous example. When the user types their login name and clicks authenticate the application makes a record of the login attempt as well as its outcome. Here's the beginning of the code that makes a record of login attempts. It does this through a call to log dot info. We'll focus our attentions solely on this line because this is the location where the attacker has the opportunity to submit data. If you're watching this video because VeriCode has flagged CRLF injection flaws in a scan of your application, chances are each flaw points to a call to a logging method within your code. In our example, the input had originated directly from the web browser, but that's not what made this operation vulnerable. Here the important part is that the application wasn't equipped to handle the possibility of CRLF sequences within this input stream. So for this reason, we demonstrated how to effectively add new lines to the underlying log file through the use of CRLFs. In order to address CRLF injection and logs, all that we must do is prevent the two characters that make up a CRLF sequence from being saved within this stream. Although there are a few alternatives, our recommended approach is to encode any input from users that is written to the log. In java applications, it's easy to do so using the logging interface of the ESAPI library by OWASP. ESAPI's logging interface is a simple abstraction designed to be easy to drop into existing projects with logging already set up. Implementations exist for both log PROJ and the native java logging package. As the ESAPI logger writes log data, it also encodes CRLF characters in order to prevent log injection attacks. To use it, let's just take the loggers we've already defined in each class and have them reference the ESAPI class instead. And that's it. We can continue to use the code we've already written. Optionally, to protect data for display in browser based log viewers, you can also set the ESAPI logger to HTML encode to the entire line. In this case, is it necessary to do so? We aren't feeding logs in the browser, and we wouldn't wish to accidentally leave the log in an unreadable state, so without a clear reason to do otherwise, we'll leave the setting off. However, if logs are used in a web component later, it would then be a good idea to turn this setting on. Decisions about risk levels and security controls are a frequent theme in the world of information security. We based this example on log file injection, but CRLF injection can also appear in forms such as HTTP response splitting. This flaw rarely appears in a readily exploitable form, but if a fix is required, the same strategy could be used in coding CRLF characters before processing them. ESAPI also provides a suite of encoding methods that can handle this. Remember that encoding transforms dangerous characters within a stream of data into representations that cannot be executed as control characters, and so in coding CRLFs and user input will effectively defeat HTTP response letting attacks. It is always a safe and good practice to verify and validate this input of the server side even after client side validation. As a final note, the flaw in our example represents just one possible instance of CRLF injection. If a VeriCode scan has reported this flaw in your application, as is the case with any tool, it's possible that the details of these issues will differ from the exploit that you've just seen. If it can be shown that CRLF sequences cannot in practice add new lines to a data stream in your application, then the flaw may be a candidate for mitigation by design. If you would like more information, please schedule a consultation call with our security consulting team, or contact VeriCode support. This has been Kevin Richard from VeriCode. Thank you very much for your time. Hello, again. This is Kevin Richard, security researcher with VeriCode and you've been watching our Appsec tutorial on CRLF injection. In our last video, we showed the sort of circumstances in which an attacker might discover and misuse this vulnerability. Now that you've gained a basic understanding of this issue, let's demonstrate how to fix it. Fortunately, this will be a quick one. First let's bring up the code from our previous example. The dominant version of Veri-Insecure utilizes the log for net library for login. When the user types their login name and clicks authenticate log for net makes a record of the login attempt and it's outcome. Here's the beginning of the code that does so. It does this through a call to log dot info. We'll focus our attention on this line alone because this is the location where an attacker has the chance to submit data. If you're watching this video because Veri-Code has flagged CRLF injection flaws in a scan of your application, chances are each flaw points to a call to a logging method within your code. In our example, the input had originated directly from the web browser, but that's not what made this operation vulnerable. Here the important part is of the application wasn't equipped to handle the possibility of CRLF sequences within this input stream. So for this reason, we demonstrated how to effectively add new lines to the underlying log file through the use of CRLFs. In order to address CRLF injection for logs, all that we have to do is to prevent the two CRLF new line characters from being saved within this stream. When using log for net, new lines are represented by a URL encoded CRLF. This is the only encoding that log for net will recognize as a new line. So it follows that HTML encoding CRLFs would neutralize their effect. Different approaches are also possible, such as string replacing the CRLF characters with blank space. But this may not work in all circumstances as it does end up changing characters inside the log and would overwrite any legitimate ones used for example in multi-line logs. So the best course of action is to prepare CRLFs with an encoding that your application does not consider to mean a new line within the given context. Here, and in many other cases, that would be HTML encoding. However we should note that no single solution is assured to work for all circumstances, so it's vital to insure that you've considered the choice and method. We've based this example on injection into log files, but CRLF injection can also appear in forms such as HTTP response splitting. This flaw rarely appears in a readily exploitable form, but if a fix is required, a different strategy can be used. Setting the enable header checking property to true. A benefit of dot net's header checking is that it will prevent header injection attacks. This strategy does not require code changes, but in situations where it is not possible you can still fall back on encoding the characters. As a final note, the flaw in our example represents just one possible instance of CRLF injection. If a VeriCode scan has reported this flaw in your application, as is the case with any tool, it's possible that the details of these issues will differ from the exploit that you've just seen. If it can be shown that CRLF sequences cannot, in practice, add new lines to a data stream in your application, then the flaw may be a candidate for mitigation by design. If you would like more information, please schedule a consultation call with our security consulting team or contact VeriCode support. This has been Kevin Richard from VeriCode. Thank you very much for your time. The scope of this course was not intended to cover every possible circumstance in which CRLF injection could arise. Rather, it was designed to convey the basic idea of this flaw. Further information is available through the following links. Thank you for viewing this Appsec tutorial on CRLF injection.