Content Security Policy (CSP) support
A Content Security Policy (CSP) is a security feature that helps prevent cross-site scripting attacks (XSS). This happens when the browser is tricked into running malicious content that appears to come from a trusted source but is really coming from somewhere else. CSPs allow the browser (on behalf of the user) to verify that the script is actually coming from a trusted source.
CSPs are implemented by adding a Content-Security-Policy
HTTP header to your server responses, or by adding a configured <meta>
element in the <head>
section of your HTML files.
Tags in Adobe Experience Platform are a tag management system that is designed to dynamically load scripts on your website. A default CSP blocks these dynamically loaded scripts due to potential security problems. This document provides guidance on how to configure your CSP to allow dynamically loaded scripts from tags.
If you want tags to work with your CSP, there are two main challenges to overcome:
- The source for your tag library must be trusted. If this condition is not met, the tag library and other required JavaScript files are blocked by the browser and won’t load on the page.
- Inline scripts must be allowed. If this condition is not met, Custom Code rule actions are blocked on the page and won’t execute properly.
Increased security requires an increased amount of work on behalf of the content creator. If you want to use tags and have a CSP in place, you have to address both of these issues without incorrectly marking other scripts as safe. The rest of this document provides guidance on how to achieve this.
Add tags as a trusted source
When using a CSP, you must include any trusted domains within the value of the Content-Security-Policy
header. The value you must provide for tags will vary depending on the type of hosting you are using.
Self-hosting
If you are self-hosting your library, then the source for your build is probably your own domain. You can specify that the host domain is a safe source by using the following configuration:
HTTP header
Content-Security-Policy: script-src 'self'
HTML <meta>
tag
<meta http-equiv="Content-Security-Policy" content="script-src 'self'">
Adobe-managed hosting
If you are using an Adobe-managed host, then your build is maintained on assets.adobedtm.com
. You should specify self
as a safe domain so you don’t break any scripts that you are already loading, but you also need assets.adobedtm.com
to be listed as safe or your tag library won’t load on the page. In this case, you should use the following configuration:
HTTP header
Content-Security-Policy: script-src 'self' assets.adobedtm.com
HTML <meta>
tag
There is a very important prerequisite: You must load the tag library asynchronously. This does not work with a synchronous load of the tag library (which results in console errors and rules not executing properly).
<meta http-equiv="Content-Security-Policy" content="script-src 'self' assets.adobedtm.com">
You should specify self
as a safe domain so that any scripts that you are already loading continue to work, but you also need assets.adobedtm.com
to be listed as safe or your library build won’t load on the page.
Inline scripts
CSP disallows inline scripts by default, and therefore must be manually configured to allow them. You have two options to allow inline scripts:
- Allow by nonce (good security)
- Allow all inline scripts (least secure)
Allow by nonce nonce
This method involves generating a cryptographic nonce and adding it to your CSP and every inline script on your site. When the browser receives an instruction to load an inline script with a nonce on it, the browser compares the nonce value to what is contained within the CSP header. If it matches, the script is loaded. This nonce should be changed with each new page load.
The examples below show how you can add your nonce to the CSP configuration for an Adobe-managed host. If you are using self-hosting, you can exclude assets.adobedtm.com
.
HTTP header
Content-Security-Policy: script-src 'self' assets.adobedtm.com 'nonce-2726c7f26c'
HTML <meta>
tag
<meta http-equiv="Content-Security-Policy" content="script-src 'self' assets.adobedtm.com 'nonce-2726c7f26c'">
Once you configure your header or HTML tag, must then tell the tag where to find the nonce when loading an inline script. For a tag to use the nonce when loading the script, you must:
- Create a data element that references where the nonce is located within your data layer.
- Configure the Core Extension and specify which data element you used.
- Publish your data element and Core Extension changes.
Allow all inline scripts unsafe-inline
If using nonces does not work for you, you can configure your CSP to allow all inline scripts. This is the least secure option, but is also easier to implement and maintain.
The examples below show how can allow all inline scripts in the CSP header.
Self-hosting
Use the following configurations if you are using self-hosting:
HTTP header
Content-Security-Policy: script-src 'self' 'unsafe-inline'
HTML <meta>
tag
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline'">
Adobe-managed hosting
Use the following configurations if you are using Adobe-managed hosting:
HTTP header
Content-Security-Policy: script-src 'self' assets.adobedtm.com 'unsafe-inline'
HTML <meta>
tag
<meta http-equiv="Content-Security-Policy" content="script-src 'self' assets.adobedtm.com 'unsafe-inline'">
Next steps
By reading this document, you should now understand how to configure your CSP header to accept the tag library file and inline scripts.
As an additional security measure, you may also opt to use Subresource Integrity (SRI) to validate fetched library builds. However, this feature has some major limitations when used with tag-management systems like tags. See the guide on SRI compatibility in Platform for more information.