?

Log in

No account? Create an account
To The Side

HTTP Response Splitting: A Common, But Frequently Unknown, Security Issue

Recently, there were two security issues discovered in Bugzilla that would fall under the category of HTTP Response Splitting attacks. Although this is a common issue in web applications, many developers are unaware of it, its consequences, or how to protect their applications from it.

In short, here's what you need to know:

Never allow unsanitized user data into HTTP headers.

Most of the time, if you're using some HTTP framework, it should be handling this for you. So mostly you just need to make sure that you have a good HTTP library that security-checks its header output properly. But if you're printing headers directly to the user, as plain text (as I've seen many PHP apps do), you do need to be concerned about this.

In particular, it's most important that you never allow any character that might be considered a "newline" into your HTTP headers. To understand why, and what could be dangerous about this, you need to know a little bit about HTTP. Let's say that we're sending a response to the user that looks like this:

200 OK
X-My-Header: some_user_data
Content-Type: text/html; charset=UTF-8

<html><head><title<Hello World!</title><body></body></html>

Okay, pretty simple. This is a page that has "Hello World!" as the title, and no content. Harmless. However, what's that X-My-Header: some_user_data there? Let's imagine that some_user_data can be anything that the user input, and he inputs a string that looks like:

some data;
Content-Type: text/html; charset=UTF-8

<script type="text/javascript">all_your_base();</script>

Now, your response looks like:

200 OK
X-My-Header: some data;
Content-Type: text/html; charset=UTF-8

<script type="text/javascript">all_your_base();</script>

Content-Type: text/html; charset=UTF-8

<html><head><title<Hello World!</title><body></body></html>

And I could have inserted anything! It's not just like a normal Cross-Site Scripting vulnerability, where I can only insert a small dangerous piece of HTML into an already-existing page. I could insert any HTML, any script, or any content at all. That content could be an ActiveX control for Internet Explorer, it could be some other content that your system is already configured to open automatically--anything. I'm not limited just to HTML or JavaScript. There's also a good chance that any Set-Cookie headers will become a part of the body instead of being part of the headers, too, so I can steal cookies even if they're marked "httponly".

For the most part, this vulnerability is prevented if you never allow people to insert a CR or LF character into headers. There's no good reason to allow inserting those characters directly into a single header, so you should be pretty safe to just completely deny those characters in HTTP headers generated by your application.

-Max
Tags: ,

Comments

Oh right, that's a good point too! I'm pretty sure header names are restricted to a pretty limited set of characters, so validating them against the RFC would be a good idea.
Oh, I suppose testing for /[A-Z][A-Za-z-]*:/, even if too lax, would be sufficient; but no space before the colon, and my point was: you can accept linebreaks if you add whitespace after each of them (to make "continuation" headers); and no empty lines (I'm not sure if a line containing one or more whitespace would terminate the headers, but there's no point in having them).
Yeah, continuation headers are theoretically allowed, but I'm not aware of any single-line limit in any HTTP client or server anywhere (unlike with email), so I really don't think there's any point in supporting them.

-Max