python / python/pythondotorg

Proposal: add a site-wide Content-Security-Policy (Report-Only first)

Open
#3,041 3 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
1.7k
Forks
700
Avg merge
2d 13h
Merged PRs (30d)
11

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

  1. Add django-csp and enable its middleware.
  2. Wire a per-request nonce into the <script> / <style> tags in the base templates.
  3. Ship a Content-Security-Policy-Report-Only policy with a reporting endpoint and collect violations for a couple of weeks.
  4. Tighten the allowlist from the reports (CDN, analytics, fonts, donate/embed widgets, and so on).
  5. 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.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

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.

Assessment

Tech stack
django, python
Domain
backend, security, web-dev
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.