Closed Bug 716801 Opened 13 years ago Closed 13 years ago

Handling of null location redirects susceptible to exploitation by CRLF injection.


(Core :: Networking: HTTP, defect)

9 Branch
Windows 7
Not set



Tracking Status
firefox-esr10 --- wontfix


(Reporter: firealwaysworks, Assigned: jduell.mcbugs)



(Whiteboard: [sg:vector-low])


(2 files)

Attached file apache_redirect.html
User Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:9.0.1) Gecko/20100101 Firefox/9.0.1
Build ID: 20111220165912

Steps to reproduce:

Firefox will ignore a null "Location:" http header and render the body of the http response normally.  This behavior makes it possible to exploit CRLF injection within a Location element of an http response header.   It should be noted that other browsers,  such as Internet Explorer are NOT susceptible to this attack. If you where to try one of the following PoCs in IE the browser will be redirected to http://localhost/ without executing the attacker's payload.   This is because IE treats a blank Location http header is treated as a null length string and the current path is prepended to the redirect location to create the redirect location.  In my experience CRLF injection is most commonly found in the "Location" header element due to user supplied input used to create a redirection path.  This type of CRLF injection attack should and can be prevented however Firefox fails to prevent them.

The XSS PoC 1 is leveraging Firefox's handling of a null location redirect to exploit a currently unpatched XSS vulnerability in Apache HTTPD v2.2.21.  This is to demonstrate that real world software is exploitable under Firefox due to this null location vulnerability, but not IE.  I have notified Apache of the XSS vulnerability and they are currently working on a suitable patch. (as of 1/9/2012)
XSS PoC 1:

In XSS PoC 2 we are introducing a <script> tag as the body of the http response by means of HTTP Response Splitting by injecting LF characters within the "Location:" http response header element.   It should be noted that if the attacker where unable to control the very beginning of this value then Firefox will correctly ignore the http body and redirect to the non-null Location value.  
XSS PoC 2:

Here is the vulnerable .py file used to execute the PoCs:

from mod_python import apache, util

def handler(req):
       input=util.FieldStorage(req, keep_blank_values=1)
       req.content_type = "text/html"
       req.headers_out.add('location', input.getfirst("url"))
       return apache.HTTP_TEMPORARY_REDIRECT

Here is a generic apache config to run the python file above:
 <Directory /var/www/>
       AddHandler python-program .py
       PythonHandler crlf
       PythonDebug On
       Options Indexes FollowSymLinks MultiViews
       AllowOverride All
       Order allow,deny
       allow from all

In case Apache has patched the XSS flaw the resulting html page has been attached.  This was included out of completeness,  you probably don't need it.
Firefox's behavior is spec-compliant so hard to call it a security vuln in Firefox, but certainly in combination with a server bug it's problematic and we should change this.

I don't think I like IE's behavior either--the victim might have a server on localhost and this becomes a firewall bypass or something. We should put up an error page if we get a redirect w/an invalid Location: header. IMO anyway, would like feedback from the network team about any compatibility issues.
Component: Untriaged → Networking: HTTP
Product: Firefox → Core
QA Contact: untriaged → networking.http
Whiteboard: [sg:vector-low]
RFC 2616 is vague is on this issue.  In the book "A Tangled Web" there are many cases where vague requirements lead to vulnerabilities in browsers. 

An error page isn't a bad idea. I have seen Firefox will throw similar errors when it is presented malformed http responses.
we throw errors for a few different skeevy location headers - I'm ok with adding this one to the list.

I think jason had the pleasure of updating code that most recently.
Asking bz to look at this in case he knows of some more appropriate error page to throw up here (but corrupt content seems fine to me).

If this looks good I can also write a test (unless we're ok with having the reporter verify it fixes the issue, which would save me a few cycles).
Assignee: nobody → jduell.mcbugs
Ever confirmed: true
Attachment #587908 - Flags: review?(bzbarsky)

While we're at it, this creates the infrastructure to barf if there are other HTTP headers that we think are fishy to see w/o a value.  If the sec-team wants to give me a list of them, we can add.  The list in nsHttpHeaderArray::IsSingletonHeader is a good place to start a list of possible contenders.

And yes, we should fix bug 688345 and give better log/console reporting for CORRUPTED_CONTENT.  I'm ok with holding this patch hostage on that work.

Really CRLF injection can exist in any header element and the attacker can make any of them non-null.  What makes a null location special is that if the location has a value then the browser will redirect without rendering the attacker's injected http body.
Comment on attachment 587908 [details] [diff] [review]
Throws CORRUPT_CONTENT if empty Location: header encountered

I'd rather see this written as:

+            if (HeaderMustHaveValue(header)) {
+                return NS_ERROR_CORRUPTED_CONTENT;
+            }
+            return NS_OK; // ignore empty headers

avoiding the else-after return.

In any case, r=me, but do add a test.  Not because we need one to verify the fix, but to keep it from regressing.
Attachment #587908 - Flags: review?(bzbarsky) → review+

added test, verified it fails w/o rest of patch.
Closed: 13 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla12
This is very useful for exploiting CRLF injection.   Can I have a CVE issued for this?
sg:low rating - we don't plan to fix this for ESR10.
Blocks: 742174
HTTPbis says that Location is a URI-Reference, and RFC 3986 says that a relative-ref is a URI-Reference, and an empty value is a valid relative-ref. So, an empty Location value is a valid value and we should treat it like IE does--as a redirect to the current location.

See bug 742174.
I think this bug report is in an invalid state, addressing 742174 would also address this bug.
Group: core-security
You need to log in before you can comment on or make changes to this bug.