Content Security Policy (CSP)
Introduction
Specifying a Content Security Policy (CSP) is a common way to secure web applications. This policy controls which scripts and styles can run on a page. You can implement it by adding a Content-Security-Policy header or using a meta tag.
Content Security Policy nonce setup
It's common practice to allow only scripts and styles from trusted domains or those with a special nonce attribute. The nonce mechanism involves two steps: defining the nonce value in the Content Security Policy and adding the same nonce value as an attribute in the styles and scripts.
Define a nonce in Content Security Policy settings
The nonce mechanism requires an additional definition in the script-src directive of the Content Security Policy:
script-src <your-sources> 'nonce-INSERT_VALID_NONCE_VALUE';
Note: The nonce value should be generated server-side and must be unique for each request. Note that
<your-sources>
is a placeholder for your permitted sources.
Add the nonce to the container code
As a result, the default container code requires the following modifications to function properly.
Asynchronous snippet: The following changes are required in this container code:
<script type="text/javascript" nonce="INSERT_VALID_NONCE_VALUE">
(function(window, document, dataLayerName, id) {
window[dataLayerName]=window[dataLayerName]||[],window[dataLayerName].push({start:(new Date).getTime(),event:"stg.start"});
var scripts=document.getElementsByTagName('script')[0],tags=document.createElement('script');
function stgCreateCookie(a,b,c){var d="";if(c){var e=new Date;e.setTime(e.getTime()+24*c*60*60*1e3),d=";expires="+e.toUTCString()}document.cookie=a+"="+b+d+"; path=/"}
var isStgDebug=(window.location.href.match("stg_debug")||document.cookie.match("stg_debug"))&&!window.location.href.match("stg_disable_debug");
stgCreateCookie("stg_debug",isStgDebug?1:"",isStgDebug?14:-1);
var qP=[];dataLayerName!=="dataLayer"&&qP.push("data_layer_name="+dataLayerName),isStgDebug&&qP.push("stg_debug");
var qPString=qP.length>0?("?"+qP.join("&")):"";
tags.async=!0,tags.src="https://client.containers.piwik.pro/"+id+".js"+qPString,tags.nonce="INSERT_VALID_NONCE_VALUE",
scripts.parentNode.insertBefore(tags,scripts);
!function(a,n,i){a[n]=a[n]||{};for(var c=0;c<i.length;c++)!function(i){a[n][i]=a[n][i]||{},a[n][i].api=a[n][i].api||function(){
var a=[].slice.call(arguments,0);"string"==typeof a[0]&&window[dataLayerName].push({event:n+"."+i+":"+a[0],parameters:[].slice.call(arguments,1)})}}(i[c])}(window,"ppms",["tm","cm"]);
})(window, document, 'dataLayer', 'feacd61d-0232-40a1-96c3-7e469f7bfa7f');
</script>
Note: To make Tag Manager work correctly, replace
INSERT_VALID_NONCE_VALUE
with the generated nonce value.
Adjusting tags to work with the Content Security Policy
In most cases, no changes are needed to make the tags work. Tag Manager will automatically insert the nonce attribute into all fired tags. The only exception is when your tag adds additional scripts or styles to the page; in such cases, you should manually add the nonce attribute.
Note: Not all third-party tools available as built-in templates are configured to work with Content Security Policy. This includes tools like Google Analytics. In these cases, refer to the documentation for each tool (e.g., https://developers.google.com/web/fundamentals/security/csp).
Tag Manager's debug mode
Note: Starting from version 18.36.0 no adjustments to the Content Security Policy will be required to use Tag Manager's debug mode. The adjustments below apply only to older versions.
To load all necessary assets from the Tag Manager debugger, define sources using the img-src
, font-src
and style-src
directives.
img-src <your-sources> client.containers.piwik.pro;
font-src <your-sources> client.containers.piwik.pro;
style-src <your-sources> client.containers.piwik.pro;
Consent Manager form assets
If Consent Manager is enabled on your website, you'll need to set the connect-src
, style-src
and img-src
directives:
connect-src <your-sources> client.piwik.pro client.containers.piwik.pro;
style-src <your-sources> 'nonce-INSERT_VALID_NONCE_VALUE';
Note: We define the tracking domain as
client.piwik.pro
for collecting visitor consents and the container domain asclient.containers.piwik.pro
for fetching consent form assets.
Consent Manager’s data subject request widget
When using a data subject request widget, you need to add a nonce attribute to its <script>
tag.
<div id="ppms_cm_data_subject" class="ppms_cm_data_subject_widget__wrapper" data-editor-centralize="true" data-main-container="true" data-root="true">
<h3 id="ppms_cm_data_subject_header" class="header3">Data requests</h3>
<p id="ppms_cm_data_subject_paragraph" class="paragraph">
Please select below the type of data request along with any special requests in the body of the message. (...)
</p>
<form id="ppms_cm_data_subject_form" class="ppms_cm_data_subject_form" data-disable-select="true">
...
</form>
<script nonce="INSERT_VALID_NONCE_VALUE">
...
</script>
</div>
JavaScript tracking client
To load all the necessary assets for the JavaScript tracking client, define the sources for script-src
, img-src
and connect-src
.
script-src <your-sources> https://client.piwik.pro/ppms.js;
img-src <your-sources> https://client.piwik.pro/ppms.php;
connect-src <your-sources> https://client.piwik.pro/ppms.php;
Note: You may need to adjust these paths if you're not using the default settings. For example, the JavaScript library might be loaded as an alternative build that doesn't conflict with the Matomo script:
https://client.piwik.pro/ppas.js
.
Tracking with a custom domain
If you have a custom tracking domain, define it using the img-src
and script-src
directives:
img-src <your-sources> your-custom-cpp-domain.com;
script-src <your-sources> your-custom-cpp-domain.com;
Allowing the site inspector extension to work on the site
Our site inspector is a Chrome browser extension that visualizes analytics data like clickmaps, heatmaps and scrollmaps on tracked pages. By default, the JavaScript tracking client adds the necessary configuration for this extension in the page's HTML. However, you can disable this behavior if needed using setSiteInspectorSetup.
Since the extension integrates with the page it runs on, additional CSP rules are required to ensure it functions properly.
connect-src <your-sources+necessary-Piwik-PRO-sources> https://client.piwik.pro/api/;
frame-src <your-sources+necessary-Piwik-PRO-sources> https://client.piwik.pro/site-inspector/;
Note: If you're using a custom domain for tracking, make sure to adjust the domain in the CSP rules accordingly.
Example Content Security Policy definition
The following example Content Security Policy setup assumes:
- Your website address: client.com
- Your account name in Piwik PRO: client
- Your container domain: client.containers.piwik.pro
- You have a Piwik PRO tag with the default tracking domain: client.piwik.pro
- Nonce value: nceIOfn39fn3e9h3sd
- The setup allows the
'self'
source which is client.com
Content-Security-Policy: default-src 'self';
script-src 'self' client.piwik.pro 'nonce-nceIOfn39fn3e9h3sd';
connect-src 'self' client.containers.piwik.pro client.piwik.pro;
img-src 'self' client.containers.piwik.pro client.piwik.pro;
font-src 'self' client.containers.piwik.pro;
style-src 'self' client.containers.piwik.pro 'nonce-nceIOfn39fn3e9h3sd';
Updated 16 days ago