CSP On Mobile is Broken

This week I reported a vulnerability on Full Disclosure and and BugTraq in Android, similar to the Same Origin Bypass earlier this year. The vulnerability I reported was a Content-Security-Policy bypass. It luckily didn't get a whole lot of attention because it was not accurate.

First, Content-Security-Policy is a HTTP header used for Security. It provides the people who build a web-application with greater client-side control over where resources come from, what resources can be used, and what external resources are allowed to be available. This header is new but has a lot of adopters despite it's "newness". The vulnerability I reported supposedly bypassed the rules specified in the CSP header by beginning a URL with a \u0000.

After more investigating I discovered many more devices and browsers were also vulnerable to this, and many things that didn't quite might sense until I figured out what was causing me such confusion. CSP on Mobile is completely broken.

What is broken?

There are several issues at play contributing to my initial confusion

First: Adoption of the standard "Content-Security-Policy:" header is very far behind on mobile. Many popular browsers are relying on legacy X-Webkit-CSP to enforce this policy. As far as I know (and after consulting a quick survey of popular sites), almost nobody actually is serving this header.

After examining Twitter's CSP headers when accessing a page that had a CSP policy while using a User-Agent string that indicated I was coming from an X-Webkit-CSP browser, the policy was still "content-security-policy"

Second: There are several oddities related to enforcement of the spec. For example, In mobile opera on Android (24.0.1565.82529), they choose to enforce the spec extremely well but they do not enforce the optional URL path. This is clearly mentioned in the spec as something that could come out at any time.

Example 4: A social network wishes to ensure that all scripts are loaded from a specific path to prevent user-generated content from being interpreted as script:

Content-Security-Policy: default-src 'self'; script-src https://example.com/js/
Unfortunately, this use case is not supported in CSP 1.0. The user agent will ignore the path and act as if the policy contained a script-src directive with value https://example.com. A future version of CSP might begin enforcing these path restrictions, however.
I believe it will be very useful for preventing data exfiltration through 3rd party APIs (by providing a whitelisted URL path that is only valid for your API, security is greatly increased). All major browsers, mobile and not, enforce this. When it comes to mobile, several popular browsers choose not to support this.

What does all this mean?

When you combine all of this together, you end up with a policy that is enforced incosistently across a ton of browsers. This means the net security win may be 0, depending on who loads the page. While this isn't completely unexpected to a certain degree, my findings show that CSP is far behind what was originally believed on mobile.

ejj, Oct 2014