Skip to the content
Documentation
Help Start
Reading in:
  • German: 9,090 of 9,090 pages
About the help in other languages
All help pages

CSP-safe design

Designing so a strict Content Security Policy can be enforced: what the policy allows by default, the three rules (no inline script, no inline style, no third-party origins), the patterns that replace inline code, the…

Download as PDF

Address: https://doc.exponential.earth/exphelp/viewer/help/designers/theme-design/csp-safe-design.md

On this page

CSP-safe design

This page is for designers whose templates must work under a Content Security Policy (CSP). A strict policy stops an injected script from running even where a template forgets to escape a value. The administration sends one; public sites can switch one on. The settings are described in Content Security Policy.

Contents

  1. The policy in brief
  2. The three rules for designs
  3. Replacement patterns
  4. The nonce: the rare exception
  5. Auditing a design

The policy in brief

site.ini [ContentSecurityPolicy] with Mode=auto (default) sends a report-only policy on administration siteaccesses and none on public sites; report-only and enforce can be set per siteaccess. The default directives allow only the site's own origin:

Directives[script-src]='self'
Directives[style-src]='self'
Directives[img-src]='self' data: blob:
Directives[font-src]='self' data:
Directives[connect-src]='self'

So: scripts and styles only from files on the same host; no inline <script>, no onclick="", no <style> blocks or style="" attributes once the policy is enforced.

The three rules for designs

  1. No inline JavaScript: no <script> with code, no on*= attributes, no javascript: links (No inline JavaScript).
  2. No inline CSS: no <style> blocks, no style="" attributes (No inline CSS).
  3. No third-party origins you have not planned: fonts, scripts, styles, frames from other hosts each need a directive change (External resources and CDNs).

Replacement patterns

Instead ofUse
<script>var cfg = {...}</script><script type="application/json" id="cfg">{json_encode(...)}</script> read by your script file
onclick="doThing()"data-action="thing" and addEventListener in a script file
<a href="javascript:...">a <button type="button"> with a listener
style="width: 40%"a class (.pct-40) or a data- value a script turns into a custom property
<style> with per-page rulesa stylesheet required by the view template (ezcss_require)
a head script that must run before painta small file loaded with ezscript in the head (The theme toggle and the pre-paint guard)

The nonce: the rare exception

With [ContentSecurityPolicy] Nonce=enabled (default) the policy carries a fresh nonce per request for the directives in NonceDirectives[] (script-src). The template operator csp_nonce() prints it:

<script nonce="{csp_nonce()}">/* code a template truly cannot move into a file */</script>

Never print csp_nonce() inside a {cache-block} or a view-cached template: the cached copy would carry another request's nonce and the script would be blocked (comments in settings/site.ini and kernel/common/expcontentsecuritypolicyoperator.php). That is why files are always the better choice.

Auditing a design

  1. Run the site with Mode=report-only for a while and read the reports: the browser console shows them, and with ReportEndpoint=enabled the kernel writes them to var/log/csp.log, listed in Setup > Log files.

  2. For administration designs and extensions, the design tests find inline code in templates:

    php vendor/bin/phpunit tests/tests/design/AdminContentSecurityPolicyTest.php
    php vendor/bin/phpunit tests/tests/design/ExtensionInlineScriptsTest.php
  3. Search your own design:

    grep -rn -E "<script>|<script [^>]*>[^<]|on(click|load|change|submit)=|javascript:|<style|style=\"" extension/mytheme/design
  4. When nothing is reported for the pages you use, switch the siteaccess to Mode=enforce.

Become an Exponential Partner

Partners share their information, provide funding, contribute back and develop the products with us, and that is how Exponential grows. A partner website and dashboard are planned for mid-2027: please become a partner today to speed up our growth rate and land new features faster.

Something wrong on this page? Report an error

Documentation license

This documentation is free documentation, licensed under the GNU Free Documentation License 1.3 or later.

Exponential Copyright © 1998-2026 Exponential Foundation and 7x