Last Comment Bug 716801 - Handling of null location redirects susceptible to exploitation by CRLF injection.
: Handling of null location redirects susceptible to exploitation by CRLF injec...
Status: RESOLVED FIXED
[sg:vector-low]
:
Product: Core
Classification: Components
Component: Networking: HTTP (show other bugs)
: 9 Branch
: x86_64 Windows 7
: -- normal (vote)
: mozilla12
Assigned To: Jason Duell [:jduell] (needinfo? me)
:
Mentors:
Depends on:
Blocks: 742174
  Show dependency treegraph
 
Reported: 2012-01-09 21:46 PST by mike
Modified: 2012-04-04 10:16 PDT (History)
5 users (show)
See Also:
Crash Signature:
(edit)
QA Whiteboard:
Iteration: ---
Points: ---
Has Regression Range: ---
Has STR: ---
wontfix


Attachments
apache_redirect.html (298 bytes, text/plain)
2012-01-09 21:46 PST, mike
no flags Details
Throws CORRUPT_CONTENT if empty Location: header encountered (2.79 KB, patch)
2012-01-11 18:19 PST, Jason Duell [:jduell] (needinfo? me)
bzbarsky: review+
Details | Diff | Review

Description mike 2012-01-09 21:46:52 PST
Created attachment 587244 [details]
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:
http://localhost/crlf.py?url=%0Ajavascript:alert%281%29;


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:
http://localhost/crlf.py?url=%0Acontent-length:%2025%0A%0A%3Cscript%3Ealert%281%29%3C/script%3E


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"))
       req.send_http_header()
       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
 </Directory>

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.
Comment 1 Daniel Veditz [:dveditz] 2012-01-11 16:55:24 PST
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.
Comment 2 mike 2012-01-11 17:38:58 PST
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.
Comment 3 Patrick McManus [:mcmanus] 2012-01-11 17:42:05 PST
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.
Comment 4 Jason Duell [:jduell] (needinfo? me) 2012-01-11 18:19:29 PST
Created attachment 587908 [details] [diff] [review]
Throws CORRUPT_CONTENT if empty Location: header encountered

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).
Comment 5 Jason Duell [:jduell] (needinfo? me) 2012-01-11 18:23:14 PST
Daniel,

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.
Comment 6 mike 2012-01-11 18:27:48 PST
Jason,

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 7 Boris Zbarsky [:bz] 2012-01-12 13:46:33 PST
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.
Comment 8 Jason Duell [:jduell] (needinfo? me) 2012-01-20 09:36:37 PST
https://hg.mozilla.org/integration/mozilla-inbound/rev/abb2ccdb82fd

added test, verified it fails w/o rest of patch.
Comment 9 Ed Morley [:emorley] 2012-01-20 18:42:51 PST
https://hg.mozilla.org/mozilla-central/rev/abb2ccdb82fd
Comment 10 mike 2012-02-10 09:52:33 PST
This is very useful for exploiting CRLF injection.   Can I have a CVE issued for this?
Comment 11 Alex Keybl [:akeybl] 2012-03-29 16:57:31 PDT
sg:low rating - we don't plan to fix this for ESR10.
Comment 12 Brian Smith (:briansmith, :bsmith, use NEEDINFO?) 2012-04-03 21:51:28 PDT
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.
Comment 13 mike 2012-04-03 22:51:28 PDT
I think this bug report is in an invalid state, addressing 742174 would also address this bug.

Note You need to log in before you can comment on or make changes to this bug.