Fix #139: drop unsafe-inline from script-src and style-src #159

Closed
fen wants to merge 0 commits from fix-139 into dev
Collaborator

Partially addresses #139 -> actually fully removes both 'unsafe-inline' allowances; written as Fixes below.

Fixes #139.

What changed

CSP is now default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; frame-ancestors 'none' — both 'unsafe-inline' allowances removed.

script-src: all inline <script> blocks (layout head/theme resolution, topbar dark toggle, foot counters, paste, new, history, mine, settings, admin, unlock) moved to external files under internal/web/static/ (theme.js, topbar.js, foot.js, paste.js, new.js, history.js, mine.js, settings.js, admin.js, unlock.js). Template data reaches scripts via data-* attributes (data-paste-id, data-default-dark on the script tags). Inline onclick handlers (copy/delete/stats) replaced with addEventListener wiring.

style-src: inline style="" attributes converted to CSS utility classes in app.css; settings swatches are now built via DOM APIs with CSSOM styles (setting them via innerHTML strings re-trips style-src, caught during rendered verification).

img-src data: intentionally stays: SVG data-URI backgrounds in app.css require it.

Verification

  • go build ./..., go vet ./..., go test ./... all pass
  • New regression tests (internal/web/csp_noinline_test.go): no inline script blocks/onclick/style attrs in templates; every /static/*.js referenced by a template exists
  • Local build served + headless chromium with --enable-logging=stderr: ZERO CSP violations on /new, /history, /mine, /settings, /admin, paste view
  • Rendered element checks: 5 theme cards / 50 swatches render on /settings; dark and light presets (?theme=midnight, ?theme=pastel-cloud, midnight-light) both resolve data-preset; admin page shows lock only with hidden panel; paste create + view works; SVG icons present on all pages
Partially addresses #139 -> actually fully removes both 'unsafe-inline' allowances; written as Fixes below. Fixes #139. ## What changed CSP is now `default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; frame-ancestors 'none'` — both `'unsafe-inline'` allowances removed. **script-src:** all inline `<script>` blocks (layout head/theme resolution, topbar dark toggle, foot counters, paste, new, history, mine, settings, admin, unlock) moved to external files under `internal/web/static/` (theme.js, topbar.js, foot.js, paste.js, new.js, history.js, mine.js, settings.js, admin.js, unlock.js). Template data reaches scripts via `data-*` attributes (`data-paste-id`, `data-default-dark` on the script tags). Inline `onclick` handlers (copy/delete/stats) replaced with addEventListener wiring. **style-src:** inline `style=""` attributes converted to CSS utility classes in app.css; settings swatches are now built via DOM APIs with CSSOM styles (setting them via innerHTML strings re-trips style-src, caught during rendered verification). `img-src data:` intentionally stays: SVG data-URI backgrounds in app.css require it. ## Verification - `go build ./...`, `go vet ./...`, `go test ./...` all pass - New regression tests (internal/web/csp_noinline_test.go): no inline script blocks/onclick/style attrs in templates; every /static/*.js referenced by a template exists - Local build served + headless chromium with --enable-logging=stderr: ZERO CSP violations on /new, /history, /mine, /settings, /admin, paste view - Rendered element checks: 5 theme cards / 50 swatches render on /settings; dark and light presets (?theme=midnight, ?theme=pastel-cloud, midnight-light) both resolve data-preset; admin page shows lock only with hidden panel; paste create + view works; SVG icons present on all pages
fen added 1 commit 2026-09-10 14:08:41 +00:00
Fix #139: drop unsafe-inline from script-src and style-src (#139)
CI / docker (pull_request) Skipped
CI / test (pull_request) Successful in 30s
7a74ff3e74
- Move all inline <script> blocks (layout head/theme, topbar dark toggle,
  foot, paste, new, history, mine, settings, admin, unlock) to external
  files under internal/web/static/. Page data reaches scripts via data-*
  attributes (data-paste-id, data-default-dark) instead of template vars.
- Replace inline onclick handlers (copy, delete, stats toggle) with
  addEventListener wiring.
- Convert inline style="" attributes to CSS utility classes; swatch
  colors are now set via CSSOM/DOM APIs instead of innerHTML strings.
- script-src/style-src are now plain 'self'; img-src data: stays for the
  SVG data-URI backgrounds. Verified with headless chromium: zero CSP
  violations on all pages in dark and light presets, theme swatches,
  admin lock, tables and paste view render correctly.
fen closed this pull request 2026-09-10 14:31:09 +00:00
fen deleted branch fix-139 2026-09-10 14:31:09 +00:00
Author
Collaborator

Merged into dev as 5a227e2 and deployed to palette-dev (CI docker run for the merge commit is the image the pod runs). Live rendered verification passed; issue #139 closed. Note: PR API shows merged=false due to the known local-merge path (merge verified via git ancestry).

Merged into dev as 5a227e2 and deployed to palette-dev (CI docker run for the merge commit is the image the pod runs). Live rendered verification passed; issue #139 closed. Note: PR API shows merged=false due to the known local-merge path (merge verified via git ancestry).

Pull request closed

This pull request cannot be reopened because the branch was deleted.
Sign in to join this conversation.