Using Google Analytics and Google Tag Manager with Content Security Policy/
July 20, 2017
Content Security Policies are extremely helpful when configured properly, but may need to be updated to properly allow Google Analytics and Google Tag Manager to function as expected. If your website is already using Content Security Policy, this blog post will explain how to modify your policy to allow Google Analytics and Google Tag Manager. Creating a new policy from scratch is outside the scope of this blog post. If you aren’t already using Content Security Policy, you don’t need to start using it to use Google Analytics or Google Tag Manager.
How Content Security Policy Works
The Content Security Policy for a webpage is sent in the “Content-Security-Policy” header of the HTTP response that contains the web page. This means that it is not part of the HTML of the web page, and cannot be accessed by viewing the page’s source code. (It is possible to deliver CSP inside the HTML through meta tags, but this is not recommended.) You will need to use the Network tab of your browser’s Developer Tools to view the Content Security Policy for a given web page.
For example, a policy might look like the following:
img-src self cdn.example.com; script-src self google.com
There is a special directive named
default-src which defines a default source list for a handful of other directives, including
connect-src. If any of the other directives are implemented they add additional restrictions the source list provided by
default-src, but if
default-src is defined it will restrict all of the different resource types affected by Content Security Policy.
How Not to Break Your Entire Website
This part is very important.
Because Content Security Policy causes the browser to refuse to load certain resources, it is quite possible for a poorly-written policy to break your website in new and exciting ways. Follow these two rules to avoid breaking your entire website and making everybody angry.
Do not add a second policy. Instead, add domains to the existing policy.
Do not add new directive names that are not already present in your policy. If one of the directives mentioned below is not already being used, simply don’t add it.
Violating either of these rules will create new restrictions on what resources can be loaded. Our goal is to update the policy to allow more resources, not fewer. Any resources that were previously allowed to load were probably being used, and restricting them from loading will probably break something.
Content Security Policy for Google Analytics
Google Analytics may make use of up to four features restricted by Content Security Policy, although it can be configured to use as few as two.
script-src directive (or your
default-src directive). Note that the www is mandatory, while the https is optional.
The easiest, but least secure, way to allow Google Analytics to run is to add the special string ‘unsafe-inline’ (with quotes) to the source list for your
script-src directive. As its name implies, this allows all inline snippets to run, and may allow unsafe code to run. The second-easiest method is to move the Google Analytics code snippet to an external code file, hosted on a domain that is already whitelisted by your
script-src directed, such as the primary domain of your website. If you are using Google Tag Manager, you have already done this! The third way is to use a
nonce-value on the inline script. The use of
nonce-values is complicated, and only recommended if you are already using
nonce-values for other inline scripts.
Google Analytics has three ways to send data to Google’s servers: Image requests, Post requests, and the browser “Beacon” feature. All three of these methods can be restricted by Content Security Policy; Image requests by the
img-src directive, and the other two by the
connect-src directive (both of these directives are affected by the
default-src directive). By default, Google Analytics uses the image tag for small requests and Post requests for large requests. This can be overridden by explicitly setting the ‘transport’ variable in order to control what resource type is used, although the Beacon method is not available in all browsers.
If directives are in place that cover any of the beacon types used on your website, either explicitly or via the
default-src directive, then Google Analytics must be whitelisted by adding https://www.google-analytics.com to the source list for those directives. If you have enabled Advertising Features or AdWords integration, you should also add https://stats.g.doubleclick.net and https://www.google.com to the source list.
The following policy is the simplest one that would allow Google Analytics to function without Advertising or AdWords features, and without allowing any other non-Google resources.
default-src 'self' https://www.google-analytics.com 'unsafe-inline'
The following policy only allows what is strictly necessary. This policy also requires that the Google Analytics code snippet be moved to a separate file hosted on the same domain as your main website.
script-src 'self' https://www.google-analytics.com;
img-src https://www.google-analytics.com www.google-analytics.com https://stats.g.doubleclick.net;
connect-src https://www.google-analytics.com www.google-analytics.com https://stats.g.doubleclick.net
Google Tag Manager
The role of Google Tag Manager is to load other assets onto your page, including asset types that might by restricted by Content Security Policy. Tag Manager itself only requires enable two features of Content Security policy, but assets loaded by Tag Manager may require other policies.
default-src) directive must be updated to include https://www.googletagmanager.com and ‘unsafe-inline’ (with the quotes) in the source list.
Content Security Policy must also be configured to allow any assets contained inside of Tag Manager. For example, if you are using Tag Manager to deploy Google Analytics, you will need to follow all of the instructions in the section above for modifying your policy to allow Google Analytics. If you are also loading additional third-party tracking pixels, you will need to figure out how to permit the appropriate image or script sources. The best way to figure out what you need to do is to try adding the tracking code in Tag Manager, preview it, and then view the error messages in your browser’s console. Browsers generally have helpful error messages about Content Security Policy violations, except for ‘unsafe-eval’ as described above.
The Debug Pane in Google Tag Manager requires an entirely different set of permissions than the rest of Tag Manager. It loads data from a different domain, and must also load style information because it is responsible for displaying visual information to the user. Because the Debug Pane is not used for general website viewing, you may want your policy to always allow these additional resources. You could use a more permissive policy on your dev servers, or see the following section about using Charles Proxy to edit the policy for a page while you are viewing it.
In order for the Debug Pane to be usable, the domain tagmanager.google.com must be added to the source list for the
script-src directive if it is defined explicitly or through the
default-src directive. Additionally, if the
style-src directive is defined, either explicitly or through the
default-src directive, then its source list must be updated to include both tagmanager.google.com and ‘unsafe-inline’ (with quotes). Content Security Policy may block additional requests for icon images and fonts, but allowing these are not necessary for the Debug Pane to be functional.
Using Charles to Modify Content Security Policy
In a previous post, I explained how to set up Charles Proxy to debug Google Analytics requests. Charles can also be used to test and debug edits to the Content Security Policy for your site, by editing the HTTP headers of requests before they are received by your browser.
From the Tools menu, select “Rewrite.” Underneath the left list, click “Add” to create a new set of Rewrite rules. In this set of rules, add a new Location at the top and enter your site’s address. Add a new rule at the bottom that will overwrite the Content Security Policy header.
Inside the rule, select “Modify Header” from the dropdown, and make sure the checkbox for Response is selected and Request is cleared. Under the “Replace” menu, enter “Content-Security-Policy” for the name and your new policy as the vale. Viola! You are in business.
Content Security Policy is a useful browser feature for enhancing the security of your website. Using it in conjunction with Google Analytics requires some coordination, but the amount of effort is minimal. In order to use Google Tag Manager, you will lose some of the benefits of CSP and you will have to do more work to manage what assets must be allowed, but it still provides significant security benefit with a manageable amount of maintenance overhead.