Problem/Motivation
Hello,
I want to share an experience when you want to use `strict-dynamic` in your CSP.
You need to use `nonce` or `hash` properties on yours scripts.
Advantages: The purpose to use nonce and hash in CSP with strict-dynamic source list keyword allows you to simplify your CSP policy by favoring hashes and nonce over domain host lists.
Actually, i have a custom module to perform extras functionality to the CSP module.
I need to overriding asset.js.collection_renderer service from core only with decorate to place nonce property to script declared from Drupal Libraries.
The class override the method render() to achieve that:
/**
* {@inheritdoc}
*
* Add nonce value to assets with src value.
*/
public function render(array $js_assets): array {
$placeholderKey = $this->nonce->getValue();
// Render the core assets.
$elements = $this->jsCollectionRenderer->render($js_assets);
// Add nonce value to assets with src value.
foreach ($elements as &$element) {
// Attributes may only be set if this script is output independently.
if (!empty($element['#attributes']['src'])) {
$element['#attributes']['nonce'] = $placeholderKey;
}
}
return $elements;
}
Perhaps, the solution exist already on CSP module, but i didn't find it, despite i search deeply.
Is it possible, to discuss about this use case ?
It could be benefic that this extra was part of the module.
Thanks
Comments
Comment #2
gappleThere's some discussion of strict-dynamic in #3086924: Allow script / style by nonce.
Since the ability to use strict-dynamic is dependent on the libraries a site uses, and previously even Drupal Core itself was incompatible, there hasn't been work to integrate it as a feature in the module.
There was also originally the issue of browser support for strict-dynamic, but I don't think that's still a concern with all modern browsers now supporting CSP 3.
I think core support, csp modules features, and browser support have all progressed enough that restoring strict-dynamic as a configurable option on the module is feasible now, but it will need some thought for implementation given that the target user for the config form is site builders. The effect of using it needs to be clear, reporting of violations visible, and easily reversible.
Comment #3
ommanipadmehum commentedThanks for the answer.
May be we can close this issue as duplicate of issue #3086924: Allow script / style by nonce to continue in it.
Comment #4
gappleI'll postpone this issue as a separate item to enable 'strict-dynamic' after making it possible to use a nonce for library scripts.
Comment #5
alieffring commentedHere's what I have done to get nonces on library scripts so that I can use `strict-dynamic`:
Create a service to override the core JsCollectionRenderer:
And implement a service provider to apply the override:
I don't know if this is the route a contrib module would want to take, but it seems to get the job done in a custom module.
Comment #6
gappleThanks for the example code @alieffring
The decorator pattern should be applied through the service definition to ensure it properly stacks with any other potential service decorators from other modules. CSP's
html_response.attachments_processor.cspservice is an example of implementing this pattern.https://symfony.com/doc/current/service_container/service_decoration.html
I still have to evaluate if it's possible/beneficial to apply the nonce earlier in the rendering pipeline and propagate it through. Theoretically the JsCollectionRenderer doesn't have assurance that the scripts it's given have come through from library definitions, but I'm not sure there's an opportunity to insert additional script urls that wouldn't also allow either modifying the library definitions or applying a nonce/hash anyways. The biggest risk is unescaped HTML that wouldn't pass through the renderer.