Problem/Motivation
A nonce-based policy only works if the value in the Content-Security-Policy header is the same value printed in the nonce attribute of each inline <script>/<style> tag. The module generates a per-request nonce (csp.nonce) and can add it to the policy (PolicyHelper::appendNonce(), or #attached['csp_nonce']). Themes, however, have no supported way to print that nonce from a Twig template.
Proposed resolution
Add a Twig extension (csp.twig_extension) with a csp_nonce() function:
<script nonce="{{ csp_nonce('script') }}">...</script>
<style nonce="{{ csp_nonce('style', "'unsafe-inline'") }}">...</style>The function returns a render array that:
- prints the
NonceBuilderplaceholder, which is replaced with the current request's nonce for each response, and - attaches
csp_nonce=>[$directive => $fallback], so the nonce is added toscript-src-elem/style-src-elemwith the same fallback handling as other render elements. No policy alter subscriber is needed.
Because the render array bubbles its attachments like any other, it works inside render-cached blocks and on Dynamic Page Cache HITs. Each response gets a new nonce that matches the header.
The value must be printed directly ({{ csp_nonce(...) }}). It can't be passed through filters, concatenated, or set on an Attribute object.
Remaining tasks
User interface changes
API changes
Data model changes
Issue fork csp-3625595
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #3
graber commented