refactor(web): document + guard sandbox CSP builder per review

Address round-1 @claude review of #1588 (no behavior change to the
enforced policy):

- approveCspSources / buildSandboxCspPolicy: document that
  resourceDomains intentionally feeds script-src/style-src per the
  McpUiResourceCsp contract, and that approve screens injection-safety
  only (not breadth — a bare `*` is accepted; safe under the
  opaque-origin sandbox).
- CSP_KEYS: replace the `satisfies` (proves listed keys valid) with an
  exhaustiveCspKeys() helper that ALSO fails to compile if the upstream
  ext-apps type gains a domain key CSP_KEYS omits, so a requested
  restriction can never be silently dropped.
- SAFE_CSP_SOURCE: accept case-insensitive schemes (URL schemes are
  case-insensitive); previously over-rejected `HTTPS://…`. Adds tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S3fTN8H3R8YV4yUGvZjYnX
This commit is contained in:
cliffhall 2026-07-01 19:17:18 -04:00
commit cb54de50d8

View file

@ -19,6 +19,12 @@ describe("SAFE_CSP_SOURCE", () => {
"data:",
"blob:",
"example.com",
// Schemes are case-insensitive per the URL spec, so a capitalized or
// mixed-case scheme is still a valid source (over-rejecting it would
// silently drop a restriction a server asked for).
"HTTPS://api.example.com",
"WSS://realtime.service.com",
"Https://*.cloudflare.com",
])("accepts %s", (s) => {
expect(SAFE_CSP_SOURCE.test(s)).toBe(true);
});