I have a web app using the default html5boilerplate Content Security Policy.
However, we have the new Google analytics.js snippet on the page, which is being blocked by the CSP.
I've been trying to find an example of a CSP and JS include structure that will allow Google analytics.js, but haven't had any luck.
The closest SO post is Google Analytics and Content-Security-Policy header, but this is using the older ga.js.
Unfortunately the Google Docs don't mention CSP.
I've reached the following solution though:
Bottom of my html file:
<script type="text/javascript" src="/js/analytics.js"></script>
Content of analytics.js:
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function()
{ (i[r].q=i[r].q||[]).push(arguments)}
,i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g; m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics/analytics.js','ga');
ga('create', 'UA-XXXXXXXX-1', 'auto');
ga('send', 'pageview');
.htaccess CSP:
Header set Content-Security-Policy "script-src 'self' ; object-src 'self'"
This works - but I'm unsure if I will have broken the asyncronous nature of the GA code, or caused some other unintended consequence.
Can someone advise the correct way to allow Google analytics.js through a Content Security Policy?
Author Edit: In the end I used the solution detailed in Google Analytics and Content-Security-Policy header, reverting back to ga.js. But I'd still like to know if it's possible to use analytics.js in the same way.
Author Edit 2: Looks like it may be possible using analytics.js direct from Google and the same principles as the other SO post:
Bottom of HTML file:
<script type="text/javascript" src=".js"></script>
<script type="text/javascript" src="/js/analytics.js"></script>
Contents of analytics.js:
ga('create', 'UA-XXXX-Y', 'auto');
ga('send', 'pageview');
CSP:
Header set Content-Security-Policy "script-src 'self' ; object-src 'self'"
This is untested - I've not checked if Google analytics is receiving data, but there are no console or CSP errors. Fingers crossed.
I have a web app using the default html5boilerplate Content Security Policy.
However, we have the new Google analytics.js snippet on the page, which is being blocked by the CSP.
I've been trying to find an example of a CSP and JS include structure that will allow Google analytics.js, but haven't had any luck.
The closest SO post is Google Analytics and Content-Security-Policy header, but this is using the older ga.js.
Unfortunately the Google Docs don't mention CSP.
I've reached the following solution though:
Bottom of my html file:
<script type="text/javascript" src="/js/analytics.js"></script>
Content of analytics.js:
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function()
{ (i[r].q=i[r].q||[]).push(arguments)}
,i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g; m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-XXXXXXXX-1', 'auto');
ga('send', 'pageview');
.htaccess CSP:
Header set Content-Security-Policy "script-src 'self' https://ssl.google-analytics.com http://www.google-analytics.com; object-src 'self'"
This works - but I'm unsure if I will have broken the asyncronous nature of the GA code, or caused some other unintended consequence.
Can someone advise the correct way to allow Google analytics.js through a Content Security Policy?
Author Edit: In the end I used the solution detailed in Google Analytics and Content-Security-Policy header, reverting back to ga.js. But I'd still like to know if it's possible to use analytics.js in the same way.
Author Edit 2: Looks like it may be possible using analytics.js direct from Google and the same principles as the other SO post:
Bottom of HTML file:
<script type="text/javascript" src="https://ssl.google-analytics.com/analytics.js"></script>
<script type="text/javascript" src="/js/analytics.js"></script>
Contents of analytics.js:
ga('create', 'UA-XXXX-Y', 'auto');
ga('send', 'pageview');
CSP:
Header set Content-Security-Policy "script-src 'self' https://www.google-analytics.com https://ssl.google-analytics.com; object-src 'self'"
This is untested - I've not checked if Google analytics is receiving data, but there are no console or CSP errors. Fingers crossed.
Share Improve this question edited May 23, 2017 at 11:54 CommunityBot 11 silver badge asked Jun 19, 2015 at 13:47 JamesGJamesG 1,6972 gold badges28 silver badges42 bronze badges 3- While I cannot, from the top of my head, can comment on the CSP I'm pretty sure that loading the GA bootstrap code at the bottom of the HTML file will pretty much make the asynch loading pointless as it only ever starts after the DOM is loaded. – Eike Pierstorff Commented Jun 19, 2015 at 14:00
- I'm having the same problem and was hoping you could confirm this solution still works or maybe post the solution you ended up using? – Brock Vond Commented Jun 19, 2016 at 1:03
- Is there any need to accept ssl.google-analytics.com anymore? Analytics.js seems to use only the www-subdomain. Using the alternative async snippet for this kind of setup would be better, and adding "async" attribute to both tags. developers.google.com/analytics/devguides/collection/… – Sampsa Suoninen Commented Jul 14, 2016 at 8:28
3 Answers
Reset to default 3You seem to have CSP headers setup on your web app, where Google Analytics domains are not white-listed yet. All the requests that the client makes to external domains should be explicitly white-listed. (This is a good reference: https://hacks.mozilla.org/2016/02/implementing-content-security-policy/).
The CSP errors you see on the browser console are quite descriptive about what has to be white-listed in your CSP header.
For example, for this case,
Refused to load the image 'https://www.google.co.in/...' because it violates the following Content Security Policy directive: "img-src ".
this would solve the error:
img-src https://www.google.co.in <other-domains>
Using the alternate way described on https://developers.google.com/analytics/devguides/collection/analyticsjs/ helped. It is much like OP described in the second edit, you can either use a custom inline script that you apply a nonce on or outsource the inline script content into a seperate script, like OP suggested. Don't forget the async attribute on the script tag that references analytics.js.
Using this method, there will be no errors/warnings as no scripts are injected to your html.
Here is the relevant part from the link I posted:
Alternative async tracking snippet
While the JavaScript tracking snippet described above ensures the script will be loaded and executed asynchronously on all browsers, it has the disadvantage of not allowing modern browsers to preload the script.
The alternative async tracking snippet below adds support for preloading, which will provide a small performance boost on modern browsers, but can degrade to synchronous loading and execution on IE 9 and older mobile browsers that do not recognize the async script attribute. Only use this tracking snippet if your visitors primarily use modern browsers to access your site.
<!-- Google Analytics -->
<script>
window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;
ga('create', 'UA-XXXXX-Y', 'auto');
ga('send', 'pageview');
</script>
<script async src='https://www.google-analytics.com/analytics.js'></script>
<!-- End Google Analytics -->
your .htaccess solution should be all correct.
why should you brake the (clientside) asynchronous nature of it ?
in the browser console you will see which requests to which hosts are blocked, if there are any blocked request from gugl while surfing the page you can add the hostname to your policy-setting