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
- 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.
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.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
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 underinternal/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 viadata-*attributes (data-paste-id,data-default-darkon the script tags). Inlineonclickhandlers (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 passMerged into dev as
5a227e2and 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