Opened 4 months ago

Last modified 2 weeks ago

#36825 assigned New feature

CSP nonces are not applied in the Django admin

Reported by: Carsten Fuchs Owned by: Antoliny
Component: contrib.admin Version: 6.0
Severity: Normal Keywords: CSP, nonce, admin
Cc: Rob Hudson, Antoliny Triage Stage: Accepted
Has patch: yes 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 (23)

comment:1 by Carsten Fuchs, 4 months ago

Description: modified (diff)

comment:2 by Natalia Bidart, 4 months 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, 4 months 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, 4 months ago

Owner: set to Kundan Yadav
Status: newassigned

comment:5 by Rob Hudson, 4 months 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 4 months ago by Rob Hudson (previous) (diff)

comment:6 by Antoliny, 4 months ago

Cc: Antoliny added

comment:8 by Natalia Bidart, 3 months ago

Needs documentation: set
Needs tests: set
Patch needs improvement: set

comment:9 by Kundan Yadav, 3 months ago

Needs tests: unset
Patch needs improvement: unset

comment:10 by Kundan Yadav, 3 months ago

Needs documentation: unset

comment:11 by Kundan Yadav, 3 months ago

hey is there anything left or wrong in the pr ?

comment:12 by Jacob Walls, 3 months ago

Patch needs improvement: set

in reply to:  11 ; comment:13 by Natalia Bidart, 3 months ago

Replying to Kundan Yadav:

hey is there anything left or wrong in the pr ?

Hello Kundan, we appreciate your eagerness to contribute! Your branch is in the review queue and will be looked at when someone is available.

Please note that Django is a community driven project and we rely on volunteers to make not only code contributions, but also other contributions such as PR reviews. If you have any availability, please consider contributing in other areas apart from code. For more details, see https://docs.djangoproject.com/en/6.0/internals/contributing/new-contributors/.

Lastly, please make sure that your PR is of the highest quality possible, to avoid back and forth on issues that could have been caught by following the Contribution checklist.

in reply to:  13 comment:14 by Kundan Yadav, 3 months ago

Replying to Natalia Bidart:

Replying to Kundan Yadav:

hey is there anything left or wrong in the pr ?

Hello Kundan, we appreciate your eagerness to contribute! Your branch is in the review queue and will be looked at when someone is available.

Please note that Django is a community driven project and we rely on volunteers to make not only code contributions, but also other contributions such as PR reviews. If you have any availability, please consider contributing in other areas apart from code. For more details, see https://docs.djangoproject.com/en/6.0/internals/contributing/new-contributors/.

Lastly, please make sure that your PR is of the highest quality possible, to avoid back and forth on issues that could have been caught by following the Contribution checklist.

i will not use llm and my next pr will be better than before

comment:15 by Antoliny, 5 weeks ago

Owner: changed from Kundan Yadav to Antoliny

comment:16 by Antoliny, 3 weeks ago

Hi Natalia and Jacob! I was looking into starting this work, but I noticed that some scripts in the admin are generated via Form.media, so would it be better to wait for this ticket to land first before proceeding?

https://code.djangoproject.com/ticket/36784

in reply to:  16 comment:17 by Natalia Bidart, 3 weeks ago

Replying to Antoliny:

Hi Natalia and Jacob! I was looking into starting this work, but I noticed that some scripts in the admin are generated via Form.media, so would it be better to wait for this ticket to land first before proceeding?

https://code.djangoproject.com/ticket/36784

Hey Antoliny, your proposal makes sense. If you have any ideas or opinions for how to solve the other ticket, please comment there. Thanks!

comment:18 by Antoliny, 3 weeks ago

Hey Antoliny, your proposal makes sense. If you have any ideas or opinions for how to solve the other ticket, please comment there. Thanks!

Thank you, Natalia! I'll start by addressing the scripts in the templates first, and then figure out the next steps depending on how the nonce support lands in Form.media.

Thanks for the quick response!

comment:20 by Antoliny, 3 weeks ago

Patch needs improvement: unset

comment:21 by Natalia Bidart, 2 weeks ago

Patch needs improvement: set

comment:22 by Natalia Bidart, 2 weeks ago

There is a new and relevant forum post re-thinking the whole CSP nonce approach here: https://forum.djangoproject.com/t/csp-nonce-support-for-form-media-classes-and-admin-scripts/44698

comment:23 by Natalia Bidart, 2 weeks ago

Patch needs improvement: unset

There is a PR that addresses this ticket in the more simple way (a tag just like you proposed Antoliny, so I will make you a co-author). But I still think it'd be worth seeing if we could have the admin using more of Media instead all the explicit script and link manually written elements.

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