Skip to content

feat(security): strict Content-Security-Policy and security headers - #42

Merged
ClaraVnk merged 1 commit into
mainfrom
feat/security-csp
Jun 30, 2026
Merged

feat(security): strict Content-Security-Policy and security headers#42
ClaraVnk merged 1 commit into
mainfrom
feat/security-csp

Conversation

@ClaraVnk

Copy link
Copy Markdown
Contributor

Context

Complete the minimal ZK stack hardening for ghostmon: a strict CSP that keeps the
in-browser Argon2 (zero-knowledge passphrase mode) working
via wasm-unsafe-eval,
plus the usual security headers.

Changes

  • Per-request security-headers middleware: strict CSP (no third-party origins,
    script-src 'self' 'nonce-…' 'wasm-unsafe-eval', style-src 'self' 'unsafe-inline',
    object-src 'none', frame-ancestors 'none', …), plus nosniff,
    Referrer-Policy, X-Frame-Options: DENY, Permissions-Policy. /docs & /redoc
    exempt (Swagger needs inline + CDN).
  • Removed all inline JS so the CSP can forbid it: the theme no-flash script carries a
    per-request nonce; onsubmit="confirm(…)" handlers → data-confirm + a small
    vendored confirm.js.

Verification

Real browser (Playwright): theme applies, delete confirmations work, and an
Argon2-passphrase private item decrypts in-page — zero CSP violations. Tests
assert the CSP (wasm-unsafe-eval + per-request nonce matching the inline script) and
the docs exemption. Full suite 215 passed; ruff + mypy(strict) green.

Harden the browser surface and make the zero-knowledge passphrase mode CSP-safe.

- A per-request security-headers middleware sets a strict CSP: no third-party
  origins, `script-src 'self' 'nonce-…' 'wasm-unsafe-eval'`, `style-src 'self'
  'unsafe-inline'`, `object-src 'none'`, `frame-ancestors 'none'`, etc. The
  `wasm-unsafe-eval` directive lets the vendored hash-wasm Argon2 module run, so the
  ZK passphrase decryption keeps working under CSP. Also nosniff, Referrer-Policy,
  X-Frame-Options: DENY and a restrictive Permissions-Policy. `/docs` /`/redoc` are
  exempt (Swagger needs inline + CDN).
- Remove inline JS so the CSP can forbid it: the one inline (theme no-flash) script
  carries the request nonce, and all `onsubmit="confirm(…)"` handlers become
  `data-confirm` wired by a small vendored `confirm.js`.

Verified in a real browser: the theme applies, delete confirmations work, and an
Argon2-passphrase private item decrypts in-page — with zero CSP violations. Tests
assert the CSP (wasm-unsafe-eval + per-request nonce matching the inline script) and
the docs exemption. Full suite 215 passed; ruff + mypy(strict) green.
@ClaraVnk
ClaraVnk merged commit 620a039 into main Jun 30, 2026
4 checks passed
@ClaraVnk
ClaraVnk deleted the feat/security-csp branch June 30, 2026 20:15
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