# Mozilla Security Bug Reveals Web Proxy Credentials
**Responsible disclosure**: The following security bug was
[reported](https://bugzilla.mozilla.org/show_bug.cgi?id=664983) to Mozilla and I
held off publishing this article until after it was fixed. The fix was
[released](https://www.mozilla.org/security/announce/2011/mfsa2011-29.html#cve-2011-2990)
with Firefox 6 today.
I recently discovered a method for obtaining the web proxy credentials of
visitors to my website. It abuses [Mozilla's](https://www.mozilla.org/)
implementation of a technology called "[Content Security
Policy](https://www.w3.org/Security/wiki/Content_Security_Policy)", which is
currently enabled in Firefox 4 and up. CSP was designed to allow website authors to describe which
origins are valid locations for certain types of content on their pages, placing
that information in an HTTP
response header.
For example, I might write a policy for this website which states that images
are only valid when fetched from grepular.com, or google.com. If one of my pages
then contains an
tag which points at facebook.com, Firefox will simply
refuse to fetch that image. The point of this technology is to help defend
against XSS, CSRF and similar attacks.
One of the features of CSP is that you can specify a report URI in the policy. If the browser detects that the
page is attempting to violate its CSP policy, it will perform a HTTP request in
the background to the URI specified in the policy header, containing information
regarding the violation. Here is an example of a CSP HTTP response header which
contains a report URI, and only allows images from my domain, and google.com:
```text
X-Content-Security-Policy: report-uri /csp-report.cgi; allow 'self'; img-src 'self' *.google.com
```
The HTTP request to the report URI is a POST request. The POSTed data contains a
chunk of JSON. That JSON
contains a number of items including the URL of the request which was blocked,
the particular part of the policy which was violated, and most importantly, the
full set of HTTP headers that would have been sent if the request wasn't
blocked. (These have been removed in Firefox 6)
At this point, some of you might have guessed where I'm going with this. When
you configure your browser to use a web proxy which requires authentication,
they generally tend to authenticate by adding a "Proxy-Authorization" HTTP
header to all requests. The web proxy software strips this header before
forwarding on the request, so as not to leak the credentials to the destination
website. However, when a CSP report HTTP request is generated, the
Proxy-Authorization header is stuffed inside the JSON in the POST request, along
with the rest of the headers! Web proxies don't expect the proxy authentication
details to be in the POST data, so don't strip it.
To test my theory, I modified my website to purposefully violate my CSP policy
so Firefox 4 and 5 would always generate a CSP report. It's completely
transparent, so nobody would notice. I then wrote a CGI script which would parse the CSP report, look for the
Proxy-Authorization data, and log it. It captured three headers of the following
format:
```text
Proxy-Authorization: Basic BASE64_ENCODED_PLAIN_TEXT_USERNAME_AND_PASSWORD==
```
The login details that the user uses to connect to their web proxy are trivially
decodable from this data. I instantly deleted this data once I confirmed it had
worked, and have now disabled the logging of it.
It also captured several headers which look like this:
```text
Proxy-Authorization: NTLM BASE64_ENCODED_SECURITY_TOKEN_WHICH_I_DONT_THINK_I_CAN_DO_ANYTHING_WITH==
```
I also noticed that certain requests contained Cookie headers (not set by my
website), which were subsequently stripped by the web proxy. I could still
access these stripped headers as they were packaged up in the JSON with the CSP
report. I'm not sure if they contained anything useful though. Several of them
had the name BCSI-CS-SOME_16_CHAR_HEX_STRING which looks to be to do with some
sort of functionality of one of the
[https://www.bluecoat.com/](https://www.bluecoat.com/) proxy products.
So what's the solution to this problem? The CSP reports should only send HTTP
headers from a trusted list. It's not safe or necessary to send the
Proxy-Authorization header, nor the Cookie headers. There are probably other
headers which will cause problems like this as well. Especially for people using
anonymising proxies. I'm not actually convinced that sending **any** of the
headers along with the report is necessary, although I'm sure the people who
wrote the spec must have had a reason. The only thing that is **needed** is the
URL which failed, and the specific part of the policy which was broken.
If you're stuck on an old version of Firefox 4/5, are using an authenticated web
proxy and are worried about this issue, you can disable Content-Security-Policy,
by setting "security.csp.enable" to "false" in "about:config"