Categories: Cookie consent, Policy

Implementing cookie consent with “Content Security Policy”

In this post I briefly explain how “Content Security Policy” could be used to enforce the cookie consent regulation by blocking third parties content.

Cookie Consent

EU cookie regulation imposes to website editors to obtain the informed  consent of visitors before setting cookies. Therefore, a website should first check that it has consent before dropping its own (unnecessary) cookies and so should the third parties that are called by the website. While it’s fairly simple for a first party to check that it has obtained consent (e.g. storing the consent in a cookie) third parties are in a different situation because they cannot read the first party cookies to deduce if consent has been granted.
Therefore the responsibility sort of shift to the first parties which are in a position to inform and obtain consent; yet they have to prevent third parties from setting cookies as long as consent has not been obtained. Tag managers are elegant solutions that can be deployed to do that. A less elegant solution is to rely on “Content Security Policy” to prevent external resources setting cookies from being loaded by the browser.

Overview of Content Security Policy

A “Content Security Policy” is a “declarative policy that lets the authors (or server administrators) of a web application inform the client about the sources from which the application expects to load resources”. This policy can be viewed as a white list of resources that can be loaded by the browser when requesting page. Content security policies can be conveyed in two forms, either through an HTTP header or in a http-equiv meta tag in the header of the HTML document .

Implementation of the policy

To comply with the cookie consent regulation, a website may simply use a “Content Security policy” to block any third party from loading content and subsequently setting cookies as long as consent has not been granted. Notice that this solution is not specific to cookies; it prevent all types of resources from being loaded thus effectively preventing all types of fingerprinting by third parties.
A quick “cookie consent” implementation is to set to check when a GET request is received if the “consent” cookie is set and to adapt the “Content-Security-Policy”: if consent has not been granted block all third parties, otherwise set the usual policy.
The easier implementation is to use JavaScript to insert the http-equiv tag in the HTML (although this is not recommended), website editors can just add the following JavaScript tag in their pages and that should do the trick:

if ( document.cookie.indexOf('hasConsent') < 0 ) {
 var hostname = window.location.hostname;
 if (hostname.indexOf("www.") ===0) hostname = hostname.substring(5);
 var meta = document.createElement('meta');
 meta.httpEquiv = "content-security-policy";
 meta.content = "script-src 'self' 'unsafe-inline' *." + hostname + "; img-src *." + hostname + "";
 document.getElementsByTagName('head')[0].appendChild(meta);
 }

A slightly more complicated solution is to set the HTTP header. The code is fairly similar but the complexity depends of the type of server you’re running. If you’re using PHP, you could do it like that:

if(!isset($_COOKIE["hasConsent"])) {
 $allowed_hosts = "*.unsearcher.org";
 header("Content-Security-Policy: script-src 'self' 'unsafe-inline' " . $allowed_hosts . "; img-src 'self' " . $allowed_hosts);
 }

Browser Support

Content security policy is still a working draft document so the feature is not supported equally by all browsers. As far as I can tell, Chrome and Safari implement all the required features, including support of the http-equiv tag. Firefox enforces policies that are set through the header but there is currently no support of the http-equiv tag. Finally Internet Explorer offers only very limited support of CSPs through  iframe sandbox property.

Testing

I’ve used BURP proxy to preview what websites would look like with content security policies blocking third parties, here are the results :

Content-Security-Policy: script-src 'self' 'unsafe-inline' *.lemonde.fr *.lemde.fr; img-src *.lemonde.fr *.lemde.fr
Content-Security-Policy: script-src ‘self’ ‘unsafe-inline’ *.lemonde.fr *.lemde.fr; img-src *.lemonde.fr *.lemde.fr
Content-Security-Policy: script-src 'self' 'unsafe-inline' *.nytimes.com *.nyt.com; img-src *.nytimes.com *.nyt.com
Content-Security-Policy: script-src ‘self’ ‘unsafe-inline’ *.nytimes.com *.nyt.com; img-src *.nytimes.com *.nyt.com
Content-Security-Policy: script-src 'self' 'unsafe-inline' *.slashdot.org  *.fsdn.com; img-src *.slashdot.org  *.fsdn.com
Content-Security-Policy: script-src ‘self’ ‘unsafe-inline’ *.slashdot.org *.fsdn.com; img-src *.slashdot.org *.fsdn.com

Conclusion

This solution is far from perfect, the main reason is that it is not supported by all browsers. Yet it provides a simple solution for website editors to block third party resources until  consent is obtained. Such solution is complementary to the tags provided on CNIL’s website that can be used to obtain consent before setting Google Analytic first party cookies.

@vtoubiana

Article info