From e590b83df09f7571fb251fe2942682fac2a745e4 Mon Sep 17 00:00:00 2001 From: clawbot <35+clawbot@noreply.example.org> Date: Mon, 5 Oct 2026 15:26:06 +0200 Subject: [PATCH] harden: drop 'unsafe-inline' from style-src (closes #328) The popup's markup no longer carries style attributes. The 42 in index.html and in the HTML the view helpers build are now Tailwind classes, each computing to the value it replaced, so style-src is 'self' in both manifests, pinned in tests/manifest.test.js. The address dot's 16 colours are written out as whole classes, because Tailwind builds only the classes it finds in the source. The Settings debug well is shown and hidden with the hidden class, since clearing an inline display no longer uncovers it. Two tests that found the colour dot by its inline style now find it by its class. Script that sets element.style is unaffected. Model: opus-5-5 --- README.md | 34 +++++---- TODO.md | 11 +++ manifest/chrome.json | 2 +- manifest/firefox.json | 2 +- src/popup/index.html | 115 +++++++++---------------------- src/popup/views/addressDetail.js | 4 +- src/popup/views/addressToken.js | 4 +- src/popup/views/helpers.js | 43 ++++++------ src/popup/views/home.js | 10 +-- src/popup/views/settings.js | 9 +-- tests/contractCreation.test.js | 4 +- tests/e2e/run.js | 2 +- tests/manifest.test.js | 15 ++-- 13 files changed, 108 insertions(+), 147 deletions(-) diff --git a/README.md b/README.md index 99f7b9e..c6f3ae9 100644 --- a/README.md +++ b/README.md @@ -814,13 +814,15 @@ discoverable. on critical screens and when space is available to allow users to disambiguate addresses visually, as a security feature. - **Tailwind CSS**: Utility-first CSS via Tailwind. No custom CSS classes for - styling. Tailwind is configured with a minimal monochrome palette. This keeps - the styling co-located with the markup and eliminates CSS file management. The - handful of classes in `styles/main.css` are not styling: `.copy-flash-*` - carries the copy feedback animation, and `.am-address` carries the rule that - an address never wraps. Both are invariants that hold in every place they - appear, and spelling either out as repeated utilities is how one of those - places drifts away from the rest. + styling, and no `style="..."` attributes, which the + [Content Security Policy](#content-security-policy) refuses. Tailwind is + configured with a minimal monochrome palette. This keeps the styling + co-located with the markup and eliminates CSS file management. The handful of + classes in `styles/main.css` are not styling: `.copy-flash-*` carries the copy + feedback animation, and `.am-address` carries the rule that an address never + wraps. Both are invariants that hold in every place they appear, and spelling + either out as repeated utilities is how one of those places drifts away from + the rest. - **Vanilla JS**: No framework (React, Vue, Svelte, etc.). The popup UI is small enough that vanilla JS with simple view switching is sufficient. A framework would add bundle size, build complexity, and attack surface for no benefit at @@ -2213,7 +2215,7 @@ a bare string in `manifest/firefox.json` (MV2): ``` default-src 'self'; script-src 'self' 'wasm-unsafe-eval'; object-src 'self'; -style-src 'self' 'unsafe-inline'; img-src 'self' data:; +style-src 'self'; img-src 'self' data:; connect-src 'self' https: http:; frame-src 'none'; form-action 'none'; base-uri 'none' ``` @@ -2225,15 +2227,17 @@ wallet's own UI. Escaping is the primary fix for that (see `src/shared/html.js`); this is the second line, so an escape that does slip cannot reach the network. -Four directives are looser than `'self'`, each for a reason that does not +`style-src 'self'` admits the stylesheet and nothing inline: both browsers +refuse a `style="..."` attribute and a `