Summary
Add a pure CSP-builder library at clients/web/src/lib/sandbox-csp.ts: validate app-supplied _meta.ui.csp requests, filter to safe sources, and wrap untrusted widget HTML in a fixed shell so the policy is always the first <head> child.
Why
The inspector plumbs _meta.ui.csp through today but never enforces it — a widget developer gets a misleading "works here". Enforcement needs a typed, unit-testable library: default-src 'none' catch-all, form-action 'none', source-allowlist filtering, attribute escaping. This issue is the standalone library only; wiring into the app bridge is a follow-up issue.
Reference implementation (PR #1510)
Re-implement informed by these changes at 33fac3f:
Depends on
Nothing — Wave 1 foundation, parallel-safe. Consumed later by the bridge-factory CSP-enforcement issue.
Notes
- Pure functions, no DOM — keep it that way so the unit tests stay trivial.
- Coverage gate ≥90 on all four dimensions.
Part of the PR #1510 decomposition (see tracking issue).
Summary
Add a pure CSP-builder library at
clients/web/src/lib/sandbox-csp.ts: validate app-supplied_meta.ui.csprequests, filter to safe sources, and wrap untrusted widget HTML in a fixed shell so the policy is always the first<head>child.Why
The inspector plumbs
_meta.ui.cspthrough today but never enforces it — a widget developer gets a misleading "works here". Enforcement needs a typed, unit-testable library:default-src 'none'catch-all,form-action 'none', source-allowlist filtering, attribute escaping. This issue is the standalone library only; wiring into the app bridge is a follow-up issue.Reference implementation (PR #1510)
Re-implement informed by these changes at
33fac3f:approveCspSources(),buildSandboxCspPolicy(),wrapSandboxedHtml(),SAFE_CSP_SOURCEvalidation (+111 lines)Depends on
Nothing — Wave 1 foundation, parallel-safe. Consumed later by the bridge-factory CSP-enforcement issue.
Notes
Part of the PR #1510 decomposition (see tracking issue).