Opened 8 hours ago

Last modified 61 minutes ago

#36825 assigned New feature

CSP nonces are not applied in the Django admin

Reported by: Carsten Fuchs Owned by: Kundan Yadav
Component: contrib.admin Version: 6.0
Severity: Normal Keywords: CSP, nonce, admin
Cc: Rob Hudson, Antoliny Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Carsten Fuchs)

When a Content Security Policy is configured in settings.py with directives that require script nonces, for example:

SECURE_CSP = {
    "object-src": [CSP.NONE],
    "base-uri": [CSP.NONE],
    "script-src": [CSP.NONCE, CSP.STRICT_DYNAMIC],
}

the Django admin interface stops working because the linked scripts used by the admin do not receive a nonce, resulting in CSP violations.

Expected behavior:
When CSP nonces are enabled, the Django admin should either automatically apply nonces to its scripts, or there should be a documented and supported way to make the admin compatible with nonce-based CSP configurations.

Change History (6)

comment:1 by Carsten Fuchs, 8 hours ago

Description: modified (diff)

comment:2 by Natalia Bidart, 8 hours ago

Cc: Rob Hudson added
Triage Stage: UnreviewedAccepted
Type: UncategorizedNew feature

Hello Carsten!

Thank you for taking the time to create this report. I have confirmed your findings:

Content-Security-Policy: The page’s settings blocked a script (script-src-elem) at http://localhost:9000/static/admin/js/theme.js from being executed because it violates the following directive: “script-src 'strict-dynamic'” admin
Content-Security-Policy: The page’s settings blocked a script (script-src-elem) at http://localhost:9000/static/admin/js/nav_sidebar.js from being executed because it violates the following directive: “script-src 'strict-dynamic'”

I am accepting this ticket as a new feature for 6.1, subject to volunteer contributions, to add nonce-based CSP support in the admin. Would you like to work on a branch?

comment:3 by Carsten Fuchs, 7 hours ago

Hello Natalia,

thanks for accepting the ticket. I’d love to help and I can try, but realistically this might land closer to Django 61.0 than 6.1 — I don’t know the admin codebase well enough to move that quickly. 🙂 So, no promises.

comment:4 by Kundan Yadav, 6 hours ago

Owner: set to Kundan Yadav
Status: newassigned

comment:5 by Rob Hudson, 3 hours ago

This is a subtle issue with regards to the nature of strict-dynamic.

The admin templates would need to add conditional nonce attributes to all script tags (both external and inline). For example:

Current (admin/base.html:9)

  <script src="{% static "admin/js/theme.js" %}"></script>

Should be:

  <script src="{% static "admin/js/theme.js" %}"{% if csp_nonce %} nonce="{{ csp_nonce }}"{% endif %}></script>

This would allow things to work in the following 4 scenarios. (Currently it seems Django 6.0 supports the first 3):

  1. when CSP middleware is not enabled (nonce is falsy, not added to header or script tags)
  2. when CSP is enabled without nonces (nonce not accessed, not added to header or script tags)
  3. when CSP uses nonces (nonce added to both tag and header)
  4. when CSP uses nonces with CSP.STRICT_DYNAMIC (nonce added to both tag and header)

The difference between 3 and 4 is that 3 would allow host-based allowlists and keyword allowlists to work. When CSP.STRICT_DYNAMIC, host-based allowlists and keyword (e.g. CSP.SELF) allowlists are ignored, so admin scripts would then require nonces.

Last edited 3 hours ago by Rob Hudson (previous) (diff)

comment:6 by Antoliny, 61 minutes ago

Cc: Antoliny added
Note: See TracTickets for help on using tickets.
Back to Top