Remove unsafe-inline from the Content-Security-Policy: move inline handlers and runtime Tailwind styles into served assets #125

Closed
opened 2026-09-21 20:43:36 +02:00 by clawbot · 2 comments
Collaborator

The Content-Security-Policy added for #91 allows 'unsafe-inline' in script-src and style-src, for two reasons found in the tree:

  • internal/templates/generator.html uses inline onclick handlers.
  • The bundled internal/static/tailwind.js builds styles in the browser and injects a <style> element at runtime.

REPO_POLICIES.md asks for a restrictive policy and a documented reason for any unsafe-inline; the reason is documented, this issue removes the need.

Definition of done

  1. The inline onclick handlers move into a script file served from internal/static, attached with addEventListener.
  2. The runtime Tailwind script is replaced by a stylesheet built ahead of time and served from internal/static (or, if that needs a build step the repo should not carry, say so on the PR with the reading taken and keep style-src as the only relaxed directive).
  3. SecurityHeaders() drops 'unsafe-inline' from script-src, and from style-src if item 2 is done; its test asserts the absence.
  4. The login and generator pages are loaded in a real browser engine or checked from served HTML under the new policy: login, URL generation and the copy button still work. State in the PR body that this was done.
  5. make check green.

Not a blocker for the beta deployment; it is hardening for 1.0.

Model: fable-5-1

The Content-Security-Policy added for https://git.eeqj.de/sneak/pixa/issues/91 allows `'unsafe-inline'` in `script-src` and `style-src`, for two reasons found in the tree: - `internal/templates/generator.html` uses inline `onclick` handlers. - The bundled `internal/static/tailwind.js` builds styles in the browser and injects a `<style>` element at runtime. `REPO_POLICIES.md` asks for a restrictive policy and a documented reason for any `unsafe-inline`; the reason is documented, this issue removes the need. ## Definition of done 1. The inline `onclick` handlers move into a script file served from `internal/static`, attached with `addEventListener`. 2. The runtime Tailwind script is replaced by a stylesheet built ahead of time and served from `internal/static` (or, if that needs a build step the repo should not carry, say so on the PR with the reading taken and keep `style-src` as the only relaxed directive). 3. `SecurityHeaders()` drops `'unsafe-inline'` from `script-src`, and from `style-src` if item 2 is done; its test asserts the absence. 4. The login and generator pages are loaded in a real browser engine or checked from served HTML under the new policy: login, URL generation and the copy button still work. State in the PR body that this was done. 5. `make check` green. Not a blocker for the beta deployment; it is hardening for 1.0. Model: fable-5-1
clawbot added this to the 1.0.0 milestone 2026-09-21 20:43:36 +02:00
Author
Collaborator

Plan, checked against next at ba5a716: the two onclick handlers in internal/templates/generator.html and the 400 KB runtime internal/static/tailwind.js, loaded by both pages, are still there.

  • The two handlers move into a small internal/static/generator.js attached with addEventListener, loaded with a plain <script src>.
  • tailwind.js goes. In its place, one small hand-written internal/static/style.css with only the rules the two pages use, loaded with <link rel="stylesheet">. The templates may swap Tailwind's utility classes for a few plain class names where that keeps the stylesheet short. No build step, no generated CSS, no new tool. The pages keep their layout, not necessarily every pixel of it.
  • SecurityHeaders() drops 'unsafe-inline' from both script-src and style-src, its comment about why goes, and its test asserts neither directive has it.
  • Check by hand in a browser engine, or from the served HTML if no browser can be run here, that the pages carry no inline script, style or handler, and that login, URL generation and the copy button work. State in the PR body which of the two was done.

Model: opus-5-5

Plan, checked against `next` at `ba5a716`: the two `onclick` handlers in `internal/templates/generator.html` and the 400 KB runtime `internal/static/tailwind.js`, loaded by both pages, are still there. - The two handlers move into a small `internal/static/generator.js` attached with `addEventListener`, loaded with a plain `<script src>`. - `tailwind.js` goes. In its place, one small hand-written `internal/static/style.css` with only the rules the two pages use, loaded with `<link rel="stylesheet">`. The templates may swap Tailwind's utility classes for a few plain class names where that keeps the stylesheet short. No build step, no generated CSS, no new tool. The pages keep their layout, not necessarily every pixel of it. - `SecurityHeaders()` drops `'unsafe-inline'` from both `script-src` and `style-src`, its comment about why goes, and its test asserts neither directive has it. - Check by hand in a browser engine, or from the served HTML if no browser can be run here, that the pages carry no inline script, style or handler, and that login, URL generation and the copy button work. State in the PR body which of the two was done. Model: opus-5-5
Author
Collaborator

Built as planned above in #185.

Model: opus-5-5

Built as planned above in https://git.eeqj.de/sneak/pixa/pulls/185. Model: opus-5-5
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/pixa#125