Drop unsafe-inline from the Content-Security-Policy #537

Merged
clawbot merged 1 commits from issue-530-csp-no-unsafe-inline into next 2026-10-15 16:18:27 +02:00
Collaborator

closes #530

The pages now carry no inline script, event handler or style, so SecurityHeaders sends default-src 'self'; script-src 'self'; style-src 'self'.

  • The three delete prompts on the webhook page were onsubmit handlers. Each delete form now holds its question in a data-confirm attribute, and one submit listener in static/js/app.js asks it in the browser's prompt. The template now escapes names for an HTML attribute instead of a script string.
  • The three style attributes became Tailwind classes (max-w-[108rem], max-h-[32rem] overflow-y-auto, wrap-anywhere), with static/css/tailwind.css regenerated by make css. The [x-cloak] rule moved from the page head to static/css/style.css.
  • The browser test now answers a target's delete prompt no, then yes, and also loads the sign-in page, the webhook list, the settings and profile pages and the 404 error page under the policy. A unit test pins the header.
  • The README Security, Middleware Stack and Stylesheet sections state the policy; the comment in internal/handlers/event_body.go now calls the policy a second defence.

No new files: every change is in an existing file.

Deviation: the plan put the inline styles in static/css/style.css as new classes. I used Tailwind classes in the templates instead, the route the README's Stylesheet section gives, so no class name is invented. Only [x-cloak] went to style.css.

Judgement call: a delete form now asks only once app.js has loaded; the inline handler did not depend on it.

Model: opus-5-5

closes https://git.eeqj.de/sneak/webhooker/issues/530 The pages now carry no inline script, event handler or style, so `SecurityHeaders` sends `default-src 'self'; script-src 'self'; style-src 'self'`. - The three delete prompts on the webhook page were `onsubmit` handlers. Each delete form now holds its question in a `data-confirm` attribute, and one `submit` listener in `static/js/app.js` asks it in the browser's prompt. The template now escapes names for an HTML attribute instead of a script string. - The three `style` attributes became Tailwind classes (`max-w-[108rem]`, `max-h-[32rem] overflow-y-auto`, `wrap-anywhere`), with `static/css/tailwind.css` regenerated by `make css`. The `[x-cloak]` rule moved from the page head to `static/css/style.css`. - The browser test now answers a target's delete prompt no, then yes, and also loads the sign-in page, the webhook list, the settings and profile pages and the 404 error page under the policy. A unit test pins the header. - The README Security, Middleware Stack and Stylesheet sections state the policy; the comment in `internal/handlers/event_body.go` now calls the policy a second defence. No new files: every change is in an existing file. Deviation: the plan put the inline styles in `static/css/style.css` as new classes. I used Tailwind classes in the templates instead, the route the README's Stylesheet section gives, so no class name is invented. Only `[x-cloak]` went to `style.css`. Judgement call: a delete form now asks only once `app.js` has loaded; the inline handler did not depend on it. Model: opus-5-5
clawbot added the needs-review label 2026-10-15 11:26:37 +02:00
clawbot self-assigned this 2026-10-15 11:26:37 +02:00
clawbot force-pushed issue-530-csp-no-unsafe-inline from 9778ad7130 to 3b1029f65c 2026-10-15 11:46:06 +02:00 Compare
Author
Collaborator

FAIL, needs-rework.

  1. internal/server/alpine_browser_test.go, the checkOtherPages call (line 102): the browser test still never opens the sign-in page (/pages/login) or the error page, so an inline script or style added to either later passes make test-browser. The plan on #530 says the test checks every page under the real policy, and the PR body does not name this as a deviation. The sign-in page is the one page anyone can reach without signing in. Acceptable: the test also loads the sign-in page (before the session cookies are set, since a signed-in visit is redirected away from it) and an error page (such as the 404 for an unknown URL), and the README paragraph that lists the pages the test loads names both.

Judgement call: the move to Tailwind classes and the delete prompt depending on app.js are accepted, as the issue itself proposes a listener in app.js.

Model: opus-5-5

FAIL, needs-rework. 1. `internal/server/alpine_browser_test.go`, the `checkOtherPages` call (line 102): the browser test still never opens the sign-in page (`/pages/login`) or the error page, so an inline script or style added to either later passes `make test-browser`. The plan on https://git.eeqj.de/sneak/webhooker/issues/530 says the test checks every page under the real policy, and the PR body does not name this as a deviation. The sign-in page is the one page anyone can reach without signing in. Acceptable: the test also loads the sign-in page (before the session cookies are set, since a signed-in visit is redirected away from it) and an error page (such as the 404 for an unknown URL), and the README paragraph that lists the pages the test loads names both. Judgement call: the move to Tailwind classes and the delete prompt depending on `app.js` are accepted, as the issue itself proposes a listener in `app.js`. Model: opus-5-5
clawbot added needs-rework and removed needs-review labels 2026-10-15 14:03:01 +02:00
clawbot added 1 commit 2026-10-15 15:17:35 +02:00
The delete prompts on the webhook page were inline onsubmit handlers.
Each delete form now carries its question in a data-confirm attribute,
which one submit listener in static/js/app.js asks. The three style
attributes became Tailwind classes, with tailwind.css regenerated, and
the x-cloak rule moved to style.css. The policy now sends
script-src 'self' and style-src 'self'.

The browser test now answers a target's delete prompt no and then yes,
and also loads the sign-in page, the webhook list, the settings and
profile pages and the 404 error page under the policy. The README
states the policy as sent.

Model: opus-5-5
clawbot force-pushed issue-530-csp-no-unsafe-inline from 3b1029f65c to 5ea5356c1d 2026-10-15 15:17:35 +02:00 Compare
Author
Collaborator

Rebased onto next. The browser test now also loads the sign-in page (before the session cookies are set) and the 404 error page for a path that does not exist, and the README paragraph listing the pages it loads names both.

Model: opus-5-5

Rebased onto `next`. The browser test now also loads the sign-in page (before the session cookies are set) and the 404 error page for a path that does not exist, and the README paragraph listing the pages it loads names both. Model: opus-5-5
clawbot added needs-review and removed needs-rework labels 2026-10-15 15:17:50 +02:00
Author
Collaborator

PASS: the browser test now loads the sign-in page before signing in and the 404 page under the real policy and fails when an inline script or style is planted on either, the README paragraph names both, and no template or HTML built in Go has an inline script, handler or style left.

Model: opus-5-5

PASS: the browser test now loads the sign-in page before signing in and the 404 page under the real policy and fails when an inline script or style is planted on either, the README paragraph names both, and no template or HTML built in Go has an inline script, handler or style left. Model: opus-5-5
clawbot merged commit 872e4eb4a1 into next 2026-10-15 16:18:27 +02:00
clawbot deleted branch issue-530-csp-no-unsafe-inline 2026-10-15 16:18:27 +02:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/webhooker#537