Proposal: add a site-wide Content-Security-Policy (Report-Only first)
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 38/100
Research direction
Start by reviewing the django-csp middleware integration and the base templates that contain inline script and style tags. Inspect the third-party origins python.org loads and determine how violation reports would be collected. Done means a Report-Only policy, nonce wiring, and a documented path for tuning the allowlist before enforcement.
Written by the indexing model from the issue text.
Description
Summary
Right now www.python.org does not send a Content-Security-Policy header (a quick check of the response headers shows only X-Frame-Options: SAMEORIGIN and HSTS). Adding a CSP would give the site meaningful defense-in-depth against XSS: even if user-influenced HTML is ever mis-sanitized, a strict script-src with no unsafe-inline stops injected scripts and javascript: URIs from executing.
This follows up on a request from @sethmlarson to propose a CSP for the python.org service.
Why Report-Only first
python.org serves some inline scripts/styles and pulls assets from a CDN plus a few third-party origins, so a strict policy dropped straight into enforcing mode would break pages. The safe path is to roll out in Content-Security-Policy-Report-Only mode first, collect violation reports, tune the allowlist, and only then switch to enforcing.
Proposed rollout
- Add
django-cspand enable its middleware. - Wire a per-request nonce into the
<script>/<style>tags in the base templates. - Ship a
Content-Security-Policy-Report-Onlypolicy with a reporting endpoint and collect violations for a couple of weeks. - Tighten the allowlist from the reports (CDN, analytics, fonts, donate/embed widgets, and so on).
- Flip Report-Only to enforcing once the reports are clean.
Starting policy (Report-Only, to be tuned from reports)
default-src 'self';
script-src 'self' 'nonce-{request_nonce}';
style-src 'self' 'nonce-{request_nonce}';
img-src 'self' data:;
font-src 'self';
connect-src 'self';
frame-ancestors 'self';
base-uri 'self';
object-src 'none';
form-action 'self';
This is only a starting point. The exact script-src / style-src / img-src / connect-src origins depend on which third-party services python.org actually loads, which the Report-Only telemetry will surface.
Open questions for maintainers
- Which third-party origins (CDN, analytics, fonts, embedded widgets, donation flow) need allowlisting?
- Nonces vs hashes for the existing inline scripts and styles?
- Preferred reporting endpoint (self-hosted report handler vs an external collector)?
Happy to open a Report-Only PR (django-csp plus nonce wiring and the starting policy above) once the approach looks right.
- Dominant language
- Python
- Stars
- 1.7k
- Forks
- 700
- Avg merge
- 1d 23h
- Merged PRs (30d)
- 14
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from python/pythondotorg
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
python/pythondotorg#3137 · 2 comments ·
-
app/pages bug
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
python/pythondotorg#2677 · 3 comments ·
-
backend easy
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
python/pythondotorg#2453 · 8 comments ·
-
bug good-first-issue
Difficulty 4/5 3-5 days Newbie friendliness 30/100
python/pythondotorg#3125 · 1 comment ·
-
bug
Difficulty 3/5 1-2 days Newbie friendliness 74/100
python/pythondotorg#3094 · 5 comments ·
All issues in python/pythondotorg
Similar issues
-
documentation help wanted
Difficulty 2/5 1-3 hours Newbie friendliness 90/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 90/100
simonw/sqlite-utils#872 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100