- Issue created by @zebda
- 🇨🇦Canada gapple
First, a nonce shouldn't be required if you (1) insert the JavaScript snippet via a library, and (2) authorize any necessary external domains in
script-src&script-src-elem.The Google Tag module and its merge request to support CSP may be a helpful reference ✨ Support Content Security Policy nonce Active . Any information the script needs for gtag configuration as well as a nonce value is passed via drupalSettings.
It only uses a nonce to authorize its script loader to add scripts from additional third party domains, but it still needs to specify those third party domains as a fallback for compatibility, otherwise expected features may be blocked when a page is unable to use a nonce due to something else on the page being incompatible.
If piwik doesn't load further scripts from a domain not already authorized in the policy, then it doesn't require a nonce.----
Using a nonce for an inline script is something that could use some improved documentation, but is not something I encourage 🙂.
My, now quite old article, on converting inline JS for D8+ only briefly covers part of it, since the nonce feature didn't exist at the time.My preferred approach is:
- Place the snippet in a file, added to the page via a library
- Alter the snippet to add the nonce value to the script element that it inserts into the page:
var scripts = document.getElementsByTagName('script')[0], tags = document.createElement('script'); tags.setAttribute('nonce', drupalSettings.csp.nonce); - If you're not hard-coding your
{{ analytics_id }}and{{ analytics_url }}values in the js file, pass them to the front-end with drupalSettings inhook_page_attachments - Make the library dependent on the
csp.noncelibrary (which implicitly requires thecore.drupalSettingslibrary.
The other option is to use a placeholder for the nonce attribute's value → on the inline script and the attribute on the inserted script element so that every request receives a new nonce value. The placeholder can be retrieved from the Nonce Builder service in the relevant theme hook to add as a template variable, and the lazy builder for replacing the placeholder added the element's
#attachedproperty or to the page viahook_page_attachments. - 🇳🇱Netherlands zebda
Thanks this is great! The nonce is added to the script, but not added to the header. How do I make sure it is also added to the csp header?
- 🇨🇦Canada gapple
The easiest way is to use attachments, either on a relevant render element or with
hook_page_attachments(), to add thecsp_nonceproperty with the necessary fallback values.
If you're adding the JS through a library, this should include youranalytics_urldomain, and any others that piwik includes, and probably notCsp::POLICY_UNSAFE_INLINE.$element['#attached']['csp_nonce'] = [ 'script' => [Csp::POLICY_UNSAFE_INLINE], ];The nonce is not automatically added to the header by using the
csp.nonceJS library as a dependency because of the need to specify fallback values.
If some other functionality on your page requires'unsafe-inline', then a nonce will not be added to the header, but any placeholders will still receive a nonce value. Automatically closed - issue fixed for 2 weeks with no activity.