Skip to content

cppa-cursor-browser: add a Content-Security-Policy header on served pages #141

Description

@clean6378-max-it

Sprint Item

#2 of 8 — Medium severity — after #1 (Monday PR 2 of 3)

Block Relations

Blocked by #1 — SRI must pin cdnjs before CSP allow-lists it
Blocks #3 (soft) — XSS test should assert the full SRI + CSP + DOMPurify stack
Repo/day Independent of #4#8

Calendar Day

Monday, July 20, 2026 (PR 2 of 3)

Planned Effort

3 story points (Medium) — sprint item #2

Problem

The app serves rendered HTML with no Content-Security-Policy header. app.py has no after_request hook, so there is no defense-in-depth layer behind DOMPurify: if a sanitizer bypass ever landed, nothing at the browser policy layer would contain it.

Goal

One PR adding a single @app.after_request hook that sets a restrictive CSP on served HTML pages, permitting the app's inline bootstrap via nonce/hash (not blanket unsafe-inline) and allowing the SRI-pinned cdnjs origin.

Scope

Part A — CSP header

Part B — inline handling (no blanket unsafe-inline)

  • Permit the inline theme-bootstrap script and handler via a per-response nonce (or hash):
    • inline <script> at base.html:9-16
    • inline onclick at base.html:43
    • inline SVG
  • Prefer nonce injection into the template; refactor inline handlers out where cheaper than nonce-ing them.

Part C — test

  • A test asserts the Content-Security-Policy header is present on a page route (and, ideally, absent/irrelevant on a JSON API route).

Out of scope

Acceptance Criteria

  • Every served HTML page carries a Content-Security-Policy header.
  • default-src is restrictive; script-src/style-src allow 'self' + https://cdnjs.cloudflare.com.
  • The inline bootstrap script + handler are permitted via nonce/hash, not a blanket unsafe-inline, or refactored out.
  • JSON API responses are unaffected.
  • A test asserts the header is present on a page route.
  • CI green; PR approved by at least 1 reviewer.

Verification

cd C:\Users\Jasen\CppAliance\cppa-cursor-browser
.\.venv\Scripts\Activate.ps1
pytest -q -k "csp or header"
python app.py
  • curl -sI http://127.0.0.1:<port>/Content-Security-Policy present.
  • Browser DevTools: no CSP violation reports on normal use; highlight.js/Marked/DOMPurify load (allowed origin); inline bootstrap runs (nonce).
  • A JSON API response does not carry the page CSP.

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions