# (Superseded) Experimenting with a 'strict-dynamic' Content Security Policy (CSP)

**URL:** https://meta.discourse.org/t/superseded-experimenting-with-a-strict-dynamic-content-security-policy-csp/295603
**Category:** Site Management
**Created:** [February 16, 2024, 1:32pm UTC](https://meta.discourse.org/t/superseded-experimenting-with-a-strict-dynamic-content-security-policy-csp/295603 "2024-02-16T13:32:56Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![Discourse](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/discourse/32/148734_2.png) [@Discourse](https://meta.discourse.org/u/Discourse)
#### Post date: [February 16, 2024, 1:32pm UTC](https://meta.discourse.org/t/superseded-experimenting-with-a-strict-dynamic-content-security-policy-csp/295603/1 "2024-02-16T13:32:56Z")

</div>

We’re experimenting with a new ‘strict-dynamic’ CSP, which should make it much easier to integrate themes, plugins and external scripts with Discourse in a secure way.

You can try out the new mode by enabling the **‘content security policy strict dynamic’** site setting. Please let us know if you have any feedback!

We hope to make this the default in the near future, and will make an #announcements topic as we get closer to that goal.

For more information, see below:

* * *

### 📜 Background

[Back in 2018](https://meta.discourse.org/t/mitigate-xss-attacks-with-content-security-policy/104243) we introduced a default Content Security Policy for Discourse. At the time, our browser support policy meant we were restricted to using ‘host-source’ values (i.e. listing URL prefixes for every script which should be allowed).

Here in 2024, there are more options available: namely, the `'strict-dynamic'` keyword. This removes the need for listing all script URLs in advance. Instead, any initially-trusted scripts (via a ‘hash’ or ‘nonce’ value) are allowed to load more scripts with minimal restrictions.

### 👀 How do I try this new mode?

Enable the **‘content security policy strict dynamic’** setting in your admin panel.

If you don’t see the setting, make sure you’re running the latest version of Discourse. The new feature was [merged on 16th February](https://github.com/discourse/discourse/commit/b1f74ab59e6fd471b8eac9b55a5cde45f56ce518) (during the `3.3.0.beta1-dev` cycle).

If you’re on our hosting and would like to expedite the update, just let us know!

### 🤔 What happens when I enable the new setting?

The `Content-Security-Policy` `script-src` directive will be updated to include a single `nonce-` value, and the `'strict-dynamic'` keyword.

All initial `<script>` tags in core and in themes will be automatically given the appropriate `nonce=` attribute. No extra work from admins or theme developers is required.

Plugins which inject their own custom `<script>` tags will need updating to support this new mode ([e.g.](https://github.com/discourse/discourse-client-performance/commit/31b6a21f265c332f76308a74b6ffe1e230622721)). We are working to collect data on how widespread this is, and will provide guidance to developers if necessary.

Any host-source values which themes or plugins are contributing will be automatically ignored (browsers do not support host-source alongside strict-dynamic).

### 🧑‍💻 What about external scripts like GTM, analytics, advertising, etc.?

They should ‘just work’, with no extra configuration required. Let us know if you run into any issues!

### ♻ Is it reversible?

Yup! While we’re running the experiment, you can turn the setting on and off and the change will take effect immediately.

### ✍ Example policies

Example Discourse policy before this change:

```plaintext
upgrade-insecure-requests;
base-uri 'self';
object-src 'none';
script-src https://meta.discourse.org/logs/ https://meta.discourse.org/sidekiq/ https://meta.discourse.org/mini-profiler-resources/ https://global.discourse-cdn.com/meta/assets/ https://meta.discourse.org/extra-locales/ https://d3bpeqsaub0i6y.cloudfront.net/highlight-js/ https://d3bpeqsaub0i6y.cloudfront.net/javascripts/ https://d3bpeqsaub0i6y.cloudfront.net/plugins/ https://d3bpeqsaub0i6y.cloudfront.net/theme-javascripts/ https://d3bpeqsaub0i6y.cloudfront.net/svg-sprite/ 'sha256-8uAKDaK4QxxCeYZl0Wxad2Nnj2tgKyA14hYBh66pnn0=' 'sha256-QFlnYO2Ll+rgFRKkUmtyRublBc7KFNsbzF7BzoCqjgA=';
worker-src 'self' https://global.discourse-cdn.com/meta/assets/ https://d3bpeqsaub0i6y.cloudfront.net/javascripts/ https://d3bpeqsaub0i6y.cloudfront.net/plugins/;
frame-ancestors 'self';
manifest-src 'self';

```

Example Discourse policy after this change:

```plaintext
upgrade-insecure-requests;
base-uri 'self';
object-src 'none';
script-src 'nonce-78uQrKOCg78iGuMAwCq2lI9E7' 'strict-dynamic';
frame-ancestors 'self';
manifest-src 'self';

```

### 📖 Resources

[MDN strict-dynamic docs](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/Sources#strict-dynamic)

[Google’s ‘Strict CSP’ documentation](https://csp.withgoogle.com/docs/strict-csp.html)

[CSP Evaluator](https://csp-evaluator.withgoogle.com/)

[Caniuse Browser Support Info](https://caniuse.com/mdn-http_headers_content-security-policy_strict-dynamic)

---

<div class="post-metadata">

### Author: ![kelv](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/kelv/32/524739_2.png) [@kelv](https://meta.discourse.org/u/kelv)
#### Post date: [July 16, 2024, 4:10am UTC](https://meta.discourse.org/t/superseded-experimenting-with-a-strict-dynamic-content-security-policy-csp/295603/2 "2024-07-16T04:10:25Z")

</div>

As the `strict-dynamic` CSP is non-optional from Discourse `v3.3.0.beta3` onwards, we’ve updated [Mitigate XSS Attacks with Content Security Policy](https://meta.discourse.org/t/mitigate-xss-attacks-with-content-security-policy/104243) and this topic will be closed.

---

<div class="post-metadata">

### Author: ![kelv](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/kelv/32/524739_2.png) [@kelv](https://meta.discourse.org/u/kelv)
#### Post date: [July 16, 2024, 4:10am UTC](https://meta.discourse.org/t/superseded-experimenting-with-a-strict-dynamic-content-security-policy-csp/295603/3 "2024-07-16T04:10:43Z")

</div>



---

<div class="post-metadata">

### Author: ![JammyDodger](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jammydodger/32/254611_2.png) [@JammyDodger](https://meta.discourse.org/u/JammyDodger)
#### Post date: [July 22, 2024, 11:27am UTC](https://meta.discourse.org/t/superseded-experimenting-with-a-strict-dynamic-content-security-policy-csp/295603/4 "2024-07-22T11:27:36Z")

</div>


