Content Security Policies
Content Security Policy (CSP) is a browser security feature that mitigates common web security threats (such as cross-site scripting and clickjacking) by explicitly defining what resources a website can load. CSP can be implemented by defining a set of policy directives in the HTTP headers of a website. It’s enforced at the browser level, with all browsers supporting a common set of policy directives.
There are two types of CSP:
-
Report-only policy: Set in the
Content-Security-Policy-Report-OnlyHTTP header, the browser won’t enforce the defined policy directives but will report violations. -
Enforced policy: Set in the
Content-Security-PolicyHTTP header, the browser enforces the defined policy directives.
Baseline policy
DaVinci uses a report-only baseline CSP for all flows that use the auth domain. This baseline CSP will begin to be enforced in July. You can override this CSP for specific flows if your environment has a custom domain.
|
This CSP is sent as a header, not as a tag or meta-tag. |
script-src 'nonce-<random>' 'strict-dynamic' 'unsafe-eval' 'unsafe-inline' https: http:; object-src 'none'; base-uri 'none';
These directives are used in the baseline policy:
-
script-src 'nonce-<random>': Only scripts tagged with the specified nonce are allowed to execute. This nonce is included in the CSP response header and automatically applied to scripts that are included in the flow.-
'strict-dynamic': Trust propagates from scripts that have the nonce to any scripts that they load. -
'unsafe-inline': Included as a fallback for older browser versions that don’t support nonces. This directive is ignored if the browser version supports nonces. -
http:: Included as a fallback for older browser versions that don’t support nonces. This directive is ignored if the browser version supports nonces. -
https:: Included as a fallback for older browser versions that don’t support nonces. This directive is ignored if the browser version supports nonces. -
'unsafe-eval': Allows certain dependencies of the DaVinci JavaScript widget to work correctly.
-
-
object-src 'none': Browser plugins such as Flash aren’t permitted to load. -
base-uri 'none': The page cannot set a base URL. This directive prevents <base> tag injection attacks.
A CSP in enforce mode can block scripts from being loaded and prevent other modifications to the page, which can cause flow executions to fail. When a violation occurs, the JavaScript console includes an error message similar to the following:
Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'nonce-rAnd0m'". Either the 'unsafe-inline' keyword, a hash ('sha256-...'), or a nonce-source ('nonce-...') is required to enable inline execution.
Using a custom CSP
Instead of using the baseline enforced CSP, you can configure any flow to use an alternate CSP in enforce mode, an alternate CSP in report-only mode, or both. This option is only available if your environment has a custom domain. Learn more in Editing flow settings.
Mitigating CSP issues
You can modify your flow or your environment to mitigate common CSP issues.
Adding scripts dynamically
Because of the strict-dynamic directive, scripts with the nonce can load additional scripts without having to explicitly add the nonce. The nonce propagates automatically on modern browsers. However, older browsers might not honor the strict-dynamic directive. For maximum compatibility across browsers, a pattern like this is recommended for loading additional scripts into the page.
const getCspNonce = () => {
const nonceScript = document?.querySelector('#davinciWidgetScriptElement')
const nonce = nonceScript?.nonce || nonceScript?.getAttribute('nonce')
return (typeof nonce === 'string' && nonce !== '') ? nonce : ''
}
const script = document.createElement('script')
script.nonce = getCspNonce()
script.src = "https://mydomain.com/myscript.js"
document.head.appendChild(script)
Inline scripts can be added in a similar way:
const getCspNonce = () => {
const nonceScript = document?.querySelector('#davinciWidgetScriptElement')
const nonce = nonceScript?.nonce || nonceScript?.getAttribute('nonce')
return (typeof nonce === 'string' && nonce !== '') ? nonce : ''
}
const script = document.createElement('script')
script.nonce = getCspNonce()
script.innerHTML = "console.log('this is an inline script')"
document.head.appendChild(script)
Adding event handlers
You can add event handlers that won’t be blocked by the CSP by avoiding the use of the setAttribute method. For example:
const btn = document.getElementById("btn");
btn.addEventListener("click", () => {
alert("clicked");
});
Managing scripts injected by network infrastructure
Network infrastructure, such as reverse proxies, can inject scripts into HTML responses. Because those scripts might not include the nonce, the browser could block them.
If you’re using network infrastructure like this, review the network infrastructure’s documentation to see if it automatically integrates with the application-defined CSP or whether any special configuration is required.
Use cases
Controlling iframe usage
The baseline CSP allows DaVinci pages to be loaded in iframes by external websites. This can expose users to the risk of clickjacking attacks, including possible harvesting of credentials. To prevent DaVinci pages from being loaded in any external website, add the following directive to your custom CSP: frame-ancestors 'none';.
Alternatively, you can allow other pages on your custom domain to load DaVinci pages in an iframe by specifying frame-ancestors 'self';. You can allow additional specified domains to load DaVinci pages by listing the domains, as follows: frame-ancestors 'self' https://example.com https://example.org;.
Report to a monitoring service
By default, CSP policy violations are logged to the browser console and contained to each end user’s computer or device.
To configure policy violations for all end users to be logged to a monitoring service, add the report-uri policy directive and specify an endpoint set up to receive CSP policy violation JSON payloads. The following examples configure the CSP report monitoring service provided by Report URI to monitor report-only policy violations:
-
For your report-only policy:
-
Configure a CSP in your flow settings to add or update the report-uri policy directive:
Content-Security-Policy-Report-Only: ... report-uri https://<subdomain>.report-uri.com/r/d/csp/reportOnly;
Replace <subdomain> with the subdomain of your Report URI account.
-
Test hosted pages and check that violations are reported to your Report URI account.
-
-
For your enforced policy:
-
Configure a CSP in your flow settings to add or update the following policy directive:
Content-Security-Policy: ... report-uri https://<subdomain>.report-uri.com/r/d/csp/enforce;
-
CSP best practices
-
Build your CSP incrementally: When implementing a CSP, it’s best to start with a minimal set of directives and gradually expand it as you identify the resources your application needs. This helps avoid breaking functionality while still enhancing security.
-
Start with report-only mode: Always begin by implementing your CSP in report-only mode. This allows you to monitor and identify any violations without blocking legitimate resources.
-
Be specific with directives and sources: When defining your CSP directives, be as specific as possible with the allowed sources. Avoid using overly broad directive values like * unless absolutely necessary, as this can undermine the security benefits of CSP.
-
Browser compatibility: Test your CSP configuration in different browsers to ensure compatibility. Some browsers might not support all CSP directives or values.
-
Monitor violations: Actively review the browser console for reported violations. This helps you understand how your policy impacts your applications and identify any missing directives or sources.
-
CSP reporting service: Consider using a CSP reporting service to collect and analyze CSP violations across all end users. This can help you identify patterns and trends in CSP violations, which can inform your security strategy.
-
Iterate and refine: Based on the reported violations, incrementally add or modify policy directives. This iterative approach minimizes the risk of breaking functionality.
-
Regularly review and update policies: Your websites and applications evolve, and so should your CSP. Regularly review your CSP configurations to ensure they remain relevant and effective:
-
New features and integrations: When adding new features or integrating with third-party services, remember to update your CSP to allow necessary resources.
-
Security audits: Include CSP review as part of your regular security audits.
-