Is EnableHeaderChecking=true enough to prevent Http Header Injection attacks?

Josef Pfleger picture Josef Pfleger · May 15, 2009 · Viewed 16.6k times · Source

Is it sufficient to have [System.Web.Configuration.HttpRuntimeSection.EnableHeaderChecking](http://msdn.microsoft.com/en-us/library/system.web.configuration.httpruntimesection.enableheaderchecking(VS.85).aspx) set to true (default) to fully prevent Http Header Injection attacks like Response Splitting etc.?

I'm asking because a white box penetration testing tool (fortify) reports exploitable http header injection issues with HttpResponse.Redirect and cookies but I haven't found a way to successfully perform an attack. (edit:..and we have EnableHeaderChecking turned on..)

Answer

Josef Pfleger picture Josef Pfleger · May 22, 2009

I've been looking at this for some time now and draw the conclusion that setting EnableHeaderChecking to true is in fact good enough to prevent http header injection attacks.

Looking at 'reflected' ASP.NET code, I found that:

  1. There is only one way to add custom HTTP headers to an HTTP response, namely using the HttpResponse.AppendHeader method
  2. HttpResponse.AppendHeader either
    • creates instances of HttpResponseHeader (internal)
    • or calls HttpResponseHeader.MaybeEncodeHeader (for IIS7WorkerRequests)
    • or assigns its respective properties (for known headers like RedirectLocation or ContentType)
  3. HttpResponseHeader instances are created before known headers like RedirectLocation or ContentType are sent (HttpResponse.GenerateResponseHeaders)
  4. The HttpResponseHeader constructor checks the EnableheaderChecking setting and calls HttpResponseHeader.MaybeEncodeHeader when set to true
  5. HttpResponseHeader.MaybeEncodeHeader correctly encodes newline characters which makes HTTP header injection attacks impossible

Here is a snippet to roughly demonstrate how I tested:

// simple http response splitting attack
Response.AddHeader("foo", "bar\n" + 
    // injected http response, bad if user provided
    "HTTP/1.1 200 OK\n" + 
    "Content-Length: 19\n" +
    "Content-Type: text/html\n\n" +
    "<html>danger</html>"
);

The above only works if you explicitly turn EnableHeaderChecking off:

<httpRuntime enableHeaderChecking="false"/>

Fortify simply doesn't take configuration into account (setting EnableHeaderChecking explicitly had no effect) and thus always reports these type of issues.