Add a Content-Security-Policy in Report-Only mode (refs #3041)#3042
Open
tonghuaroot wants to merge 1 commit into
Open
Add a Content-Security-Policy in Report-Only mode (refs #3041)#3042tonghuaroot wants to merge 1 commit into
tonghuaroot wants to merge 1 commit into
Conversation
www.python.org currently sends no Content-Security-Policy header. This adds one via django-csp as defense-in-depth against XSS, starting in Report-Only mode so violations can be collected and the allowlist tuned before the policy is enforced. The middleware follows the existing XFrameOptionsMiddleware pattern. Refs python#3041.
ffd5621 to
69eef9e
Compare
sethmlarson
reviewed
Jul 2, 2026
sethmlarson
left a comment
Contributor
There was a problem hiding this comment.
Thanks, two comments:
| X_FRAME_OPTIONS = "SAMEORIGIN" | ||
| SILENCED_SYSTEM_CHECKS = ["security.W019"] | ||
|
|
||
| ### django-csp (Content-Security-Policy) |
Contributor
There was a problem hiding this comment.
Add a comment to remove this and our dependency on django-csp when we upgrade to Django 6.0.
|
|
||
| # Report-Only first: collect violations and tune the allowlist before | ||
| # enforcing. Rollout tracked in #3041. | ||
| CONTENT_SECURITY_POLICY_REPORT_ONLY = { |
Contributor
There was a problem hiding this comment.
Can we add a test case that checks which HTTP header is emitted? Want to make sure Content-Security-Policy-Report-Only is emitted, not Content-Security-Policy so we don't break everyone on rollout.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of #3041 (adds the CSP in Report-Only mode; enforcing and origin tuning to follow).
What this does
www.python.org currently sends no
Content-Security-Policyheader. This adds one viadjango-cspas defense-in-depth against XSS.It ships in Report-Only mode: responses carry
Content-Security-Policy-Report-Onlyand no enforcingContent-Security-Policy, so nothing is blocked for users. The point of this first step is to collect violation reports and tune the allowlist before switching to an enforced policy.Changes
pyproject.toml/uv.lock: adddjango-csp==4.0.pydotorg/settings/base.py:csp.middleware.CSPMiddlewaretoMIDDLEWARE, alongside the existingXFrameOptionsMiddleware(which is how the site already sets a security header from Django).CONTENT_SECURITY_POLICY_REPORT_ONLYpolicy with a strict starting set of directives.Starting policy
These are intentionally strict so the Report-Only telemetry surfaces every inline script/style and third-party origin that needs a nonce, hash, or allowlist entry. Follow-ups from #3041: add a report endpoint, tune the origins, wire nonces into the base templates, then flip Report-Only to enforcing.
Verification
Smoke-tested the config against django-csp 4.0 in isolation: it emits the
Content-Security-Policy-Report-Onlyheader with the directives above and no enforcingContent-Security-Policyheader, so pages are never blocked.