Detect the Same-Origin Redirection with a bug in Firefox's CSP Implementation

Summary

Firefox’s bug in CSP implementation, which will be fixed in Firefox 62, provides us the way to detect the redirection of any given URL when accessed with the victim’s Firefox. Practically, OAuth is one of interesting features which requires redirections. Here is a PoC (Fingerprinting with CSP violation) which detects the following points:

  • whether you have logged in Facebook with your Firefox.
  • (if you are logged in FB,) whether you have logged in a site (in this case, foursquare.com, cybozulive.com, www.ikyu.com) with Facebook Login. It works only with Firefox (<= 61). Firefox (<= 61) allows us to know whether a user who opened the page have ever used Facebook Login for some webpages or not.

Content-Security-Policy and the redirection

Some years ago @homakov reported the malicious use case of CSP (Content-Security-Policy) in his blog: Using Content-Security-Policy for Evil. It uses the behavior of CSP when a redirection occurs. Content Security Policy Level 2 provides some mitigations for this problem, but even now we can detect a Cross-Origin redirection from another Origin with CSP; Origin A can know whether Origin B redirects to Origin C.

In more detail, let’s observe how the following code acts with Content-Security-Policy: script-src a.example.com b.example.com/foo:

<script src="//a.example.com/example">

The behavior of the code will be classified into the following 4 patterns:

  1. if //a.example.com/example returns the status code 200, nothing interesting happens and it will be loaded..
  2. if //a.example.com/example redirects to //a.example.com/anotherexample.php`, nothing interesting happens and it will be loaded.
  3. if //a.example.com/example redirects to //b.example.com/bar, no violation occurs and it will be loaded even if the policy allows b.example.com/foo`. This is a countermeasure for path information leakage reported by @homakov.
  4. if //a.example.com/example redirects to //c.example.com/bar`, a violation occurs and the redirect will be blocked.

In other words, we can detect the redirect through CSP’s report (report-to or report-uri directives work). For example, when you want to know whether https://a.example.com/path/file redirects to other Origin, all you have to do is to prepare the following HTML with Content-Security-Policy: script-src a.example.com; report-to /report:

<script src="https://a.example.com/path/file">

If it redirects to other Origin in the browser that loads this code, a violation will be sent to /report. This allows us to know that the Cross-Origin redirection occurs from another Origin.

However, a Same-Origin redirection cannot be detected with this technique. First, whitelist-based policy (e.g. script-src a.example.com/path/file) allows all the Same-Origin redirection even if the path is specified because the path in the policy is ignored as to the redirection. Besides, the nonce-based redirection won’t cause any violation even if some Cross-Origin and Same-Origin redirection occurs; it is reasonable for the policy with nonce. So, Origin A cannot observe that a content provided in Origin B redirects other content inside the Same-Origin (B).

A bug in Firefox’s CSP implementation (FIXED in Firefox 62)

Recently, a bug in Firefox’s CSP implementation was reported: CSP: Scripts with valid nonce get blocked if URL redirects. This bug allows us to detect the redirection to a Same-Origin content.

For example, how does Firefox work with the following HTML code (now let nonce be a legitimate one)?

<script nonce="foobar" src="https://a.example.com/file1">

Now let’s think the case when https://a.example.com/file1 redirects to a Cross-Origin content (e.g. https://b.example.com/otherorigin). Unlike other browsers, Firefox reports a violation with the policy script-src 'nonce-foobar' and block it. Additionally, Firefox blocks loading the script when https://a.example.com/file1 redirects to a Same-Origin content (e.g. https://a.example.com/sameorigin).

To sum up, Firefox’s CSP implementation reports a violation when nonce-based policies are adopted and a redirect occurs! This enables us to detect the all redirection of a content from an Origin different to the one of the content.

Application

If even a Same-Origin redirection can cause a CSP violation, they can be reported with report-to (or report-uri) directive.

Case Study: Facebook Login

OAuth is one of interesting features which requires redirections. One of the examples is Facebook Login, which is provided in many web services.

Let’s look how an application with Facebook work carefully. Once a user requested the OAuth process, a HTTP request to Facebook (like https://facebook.com/dialog/oauth?scope=email&redirect_uri=https%3A%2F%2Fexample.com&client_id=[the App's client ID]) will occurs. Then, Facebook reacts differently depending on the user’s state:

  1. If the user has ever permitted the use of the application and the Re-Authentication is disabled, it redirects to the page specified with redirect_uri (in almost all the cases it is a Cross-Origin redirection).
  2. If the user has ever permitted the use of the application and the Re-Authentication is enabled, it redirects to reauth.php in www.facebook.com (Same-Origin).
  3. If the user has never permitted the use of the application, it returns a webpage with a status code 200.
  4. If the user is not logged in, it redirects to login.php in www.facebook.com (Same-Origin).

Some Cross-Origin and Same-Origin redirection occurs.

Now we can prepare a application (now we call that App A) which nobody has never permitted, which enables us to detect the state 4 (because the user cannot permit App A, so if the redirection occurs it must be the case 4). Besides, the violation report of CSP includes the host name which was blocked by CSP. It means that when the Same-Origin redirection are blocked by CSP, the report says www.facebook.com is blocked; this allows us to tell the case 1 from the case 2. If no violation report is sent, we can know the case 3 occurs.

Here is a PoC (Fingerprinting with CSP violation) which detects the following points with this technique:

  • whether you have logged in Facebook with your Firefox.
  • (if you are logged in FB,) whether you have logged in a site (in this case, foursquare.com, cybozulive.com, www.ikyu.com) with Facebook Login.

Please note that it works only with Firefox (<= 61). Have a happy CSP! :-)

Written on July 19, 2018