Skip to content

feat(web): tighten CSP and add cross-origin isolation headers#42

Merged
passcod merged 1 commit into
mainfrom
web-csp-isolation
Jun 19, 2026
Merged

feat(web): tighten CSP and add cross-origin isolation headers#42
passcod merged 1 commit into
mainfrom
web-csp-isolation

Conversation

@passcod

@passcod passcod commented Jun 19, 2026

Copy link
Copy Markdown
Member

🤖 The nightly ZAP baseline surfaced a second tier of findings once the initial security headers (#39) were in place — ZAP runs deeper passive checks once a CSP exists. This resolves the real ones and triages the rest. Verified by running the ZAP baseline locally against the stub stack: 0 WARN-NEW.

Fixed in code

  • CSP: Wildcard Directive [10055]connect-src no longer uses the https: scheme wildcard. It now names the exact WebTransport origin (the request host on wt_port, reconstructed the same way auth::handle_connect builds wt_url), so the header is built per-request.
  • Cross-Origin- headers [90004]* — added Cross-Origin-Embedder-Policy: require-corp, Cross-Origin-Opener-Policy: same-origin, and Cross-Origin-Resource-Policy: same-origin. The console embeds no third-party content, so full site isolation is safe.

Triaged as IGNORE in .zap/rules.tsv

  • style-src unsafe-inline [10055] — required by the Emotion/MUI toolkit, which injects runtime inline styles and style= attributes. Can't be dropped without server-side nonce templating of the embedded SPA. The rest of the CSP stays tight in code and is guarded by a unit test.
  • Timestamp Disclosure [10096] and Private IP Disclosure [2] — false positives in the minified bundle; the 10.0.0.1 is an example placeholder in a host-entry form field (Services.tsx).
  • Modern Web Application [10109] — informational SPA detection.

Notes

COEP: require-corp changes resource-loading semantics in the browser; the Playwright e2e suite exercises the real app and will catch any regression. Spec item transport.http.security-headers updated accordingly, with the unit test extended to assert the precise connect-src origin and the isolation headers.

The nightly ZAP baseline surfaced a second tier of findings once the initial
security headers were in place. Address the real ones and triage the rest:

- Scope CSP connect-src to the exact WebTransport origin (the request host on
  wt_port) instead of the 'https:' scheme wildcard, building the header
  per-request. Fixes ZAP 10055 'Wildcard Directive'.
- Add the cross-origin isolation headers (COEP require-corp, COOP same-origin,
  CORP same-origin); the console embeds no third-party content. Fixes ZAP 90004.
- Triage the remaining passive findings as IGNORE in .zap/rules.tsv: timestamp
  and private-IP disclosure (false positives / our own placeholder in the
  minified bundle), Modern Web Application (informational), and style-src
  'unsafe-inline' (required by the Emotion/MUI toolkit).

Verified by running the ZAP baseline locally against the stub stack: 0 WARN-NEW.
@passcod passcod merged commit f24748a into main Jun 19, 2026
11 checks passed
@passcod passcod deleted the web-csp-isolation branch June 19, 2026 16:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant