HTTP Header Injection Vulnerability



HTTP Response Splitting was discovered several years ago.  It allows attackers to split a HTTP response into multiple ones by injecting malicious response HTTP headers.  This attack can deface web sites, poison cache and trigger cross-site scripting.
Rather than splitting responses, I want to demo how to poison user cookies by using Response.Cookies as an attack vector.
Normally, http://www.mysite.com/test/default.aspx?text=esiu sets the cookie [username] with a value of "esiu".  Let's examine the code below. 
// Query parameter text is not checked before saving in user cookie
NameValueCollection request = Request.QueryString;
// Adding cookies to the response
Response.Cookies["userName"].Value = request["text"];
Unfortunately, a grave security mistake is made because input is not checked properly.  You may think, "Big deal?  A random cookie value can be saved on a user browser.  What is the harm?"
Here come along an evil hacker.  The hacker uses the following URL: http://www.mysite.com/test/default.aspx?text=esiu%0D%0ASet-Cookie%3A%20HackedCookie=Hacked.  Let's dissect this, and see what harm the hacker intends to do.
Set-Cookie header is used in HTTP response to request browser to save a cookie.  %0D%0A is a newline character on a HTTP response encoded by URL encoding, which is usually represented as "\r\n" in code.  In other words, the evil hacker is trying to use the newline character as a line separator to add Set-Cookie header immediately after the original cookie.  As a result, a malicious HackedCookie is added with a value of "Hacked".
Let's examine the HTTP response headers of both benign and evil requests to better illustrate this attack.
You should see the following segment in the HTTP response with the benign request.
HTTP/1.1 200 OK
Server: Microsoft-IIS/5.1
Date: Thu, 20 Sep 2007 20:11:50 GMT
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Set-Cookie: userName=esiu
Cache-Control: private
Content-Type: text/html; charset=utf-8
Here is the response header with the injected Set-Cookie header.  Note the underlined Set-Cookie header.
HTTP/1.1 200 OK
Server: Microsoft-IIS/5.1
Date: Thu, 20 Sep 2007 20:11:50 GMT
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Set-Cookie: userName=esiu
Set-Cookie: HackedCookie=Hacked

Cache-Control: private
Content-Type: text/html; charset=utf-8
ASP.NET 2.0 has made this attack almost impossible because by default, "\r\n" is disallowed in methods that involve HTTP response headers.  You need “enableHeaderChecking” set to false in web.config in order to pull off this attack.  Not many valid user scenarios require applications to turn off “enableHeaderChecking”
Here is the response header with "enableHeaderChecking" turned on.  Note that %0D%0A is interpreted literally.
HTTP/1.1 200 OK
Server: Microsoft-IIS/5.1
Date: Thu, 20 Sep 2007 20:11:50 GMT
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Set-Cookie: userName=esiu%0D%0ASet-Cookie: HackedCookie=Hacked
Cache-Control: private
Content-Type: text/html; charset=utf-8
It is good to be educated, but you should be safe.