Skip to content

security(frontend): add restrictive CSP and dependency audit gate - #271

Open
woahwhattheheck wants to merge 1 commit into
YieldVault-Org:mainfrom
woahwhattheheck:latch/yieldvault-263-csp-audit
Open

woahwhattheheck wants to merge 1 commit into
YieldVault-Org:mainfrom
woahwhattheheck:latch/yieldvault-263-csp-audit

Conversation

@woahwhattheheck

Copy link
Copy Markdown

Summary

Closes #263.

Adds a production-quality Content-Security-Policy, related hardening headers, and a dependency vulnerability/license CI gate so the wallet-facing UI constrains runtime script sources and fails closed on critical supply-chain findings.

Design

  • Single source of truth: security/policy.mjs (CSP directives, justified exceptions, audit/license policy).
  • Hosting configs generated via npm run security:emit-headers → public/_headers (Netlify/Cloudflare Pages) and vercel.json (Vercel).
  • vite preview applies the same headers (dev HMR intentionally excluded so Vite keeps working).
  • Freighter-style wallets use an extension content-script bridge; page connect-src allowlists Horizon + Soroban RPC origins from src/lib/networks.js (plus Futurenet for contributors).

CSP exceptions (justified)

Exception Why
style-src 'unsafe-inline' React dynamic inline styles (e.g. ChartContainer aspect-ratio); script-src stays strict
img-src data: blob: html2canvas chart export object URLs
connect-src Stellar Horizon/Soroban Required network endpoints for wallet-backed reads/submits
worker-src blob: Vite / SDK blob workers without opening remote worker hosts

Full write-up: docs/CSP.md.

Dependency CI policy

  • Fail on critical npm audit findings.
  • Warn on high/moderate/low (logged, non-blocking).
  • Fail on disallowed licenses (AGPL/GPL/SSPL/BUSL/proprietary, etc.).
  • Warn on UNKNOWN licenses.

Acceptance criteria

  • Production responses include the intended CSP and related security headers (_headers, vercel.json, preview smoke)
  • Build/CI fails on policy-defined critical dependency findings (npm run audit:deps)
  • Wallet functionality preserved through explicitly allowed Stellar origins (WALLET_CONNECT_ORIGINS aligned to NETWORKS)

Test evidence

  • test/security/csp.test.js — directives, no unsafe-inline/unsafe-eval in script-src, NETWORKS origin coverage, documented exceptions
  • test/security/headers-integration.test.js — _headers / vercel.json sync + CI wire-up regression
  • test/security/deps-policy.test.js — fail-on-critical policy + license allow/deny
  • npm run smoke:headers — preview serves CSP; no inline script bodies / secret-shaped HTML

Commands:

  • npm test — 230 passed
  • npm run audit:deps — OK (0 critical; high/moderate warned)
  • npm run build — clean (tsc -b + vite)
  • npm run smoke:headers — OK

Compatibility / rollout

  1. Confirm the deploy host honors public/_headers or vercel.json.
  2. After deploy, curl production and verify Content-Security-Policy matches security/policy.mjs.
  3. New wallet providers: extend WALLET_CONNECT_ORIGINS + CSP_EXCEPTIONS, re-emit headers, extend tests.
  4. Dev (npm run dev) does not apply production CSP; use npm run preview / smoke:headers for parity.

Out of scope

  • Broad wallet-provider rewrite
  • Upgrading major dependency majors solely to clear non-critical advisories

Closes YieldVault-Org#263.

Ship a production Content-Security-Policy with related hardening headers
from a single policy module, emit Netlify/Vercel hosting configs, apply the
same headers on vite preview, and fail CI on critical npm audit findings or
disallowed licenses. Document justified exceptions for React inline styles,
html2canvas blob URLs, and Stellar Horizon/Soroban RPC origins used by
Freighter-style wallet flows.
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.

security(frontend): add a restrictive content security policy and dependency audit gate

1 participant