fix: proper CSP handling in basic-host sandboxing (HTTP headers, worker-src, document.write) (#234)
* fix: Move CSP to HTTP headers + add worker-src, frameDomains, baseUriDomains, permissions Security improvements: - CSP is now set via HTTP headers in serve.ts instead of meta tags (meta tag CSP can be tampered with by same-origin content) - CSP passed as query param to sandbox.html for header-based enforcement New CSP/permissions features (borrowed from PR #158): - frameDomains: control frame-src directive for nested iframes - baseUriDomains: control base-uri directive - permissions: camera, microphone, geolocation via iframe allow attribute WebGL fix: - Use document.write() instead of srcdoc for inner iframe content (srcdoc creates opaque origin that breaks WebGL canvas updates) - Add worker-src directive with blob: support (critical for WebGL apps like CesiumJS/Three.js that use workers for tile decoding, terrain processing, image processing) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor: Remove permissions support (defer to PR #158) Keep this PR focused on CSP security fixes only. Permissions (camera, microphone, geolocation) will be handled in #158. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * cleanup McpUiResourceCsp type usage / duplicate defs * fix: guard against CSP injection in domain parameters Validate CSP domain entries to reject characters that could: - Break out of CSP directives (semicolons, newlines) - Inject CSP keywords like 'unsafe-eval' (quotes) - Inject multiple sources in one entry (spaces) This prevents injection attacks where malicious domains could override the security policy. --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
df49e88b2d
commit
8b09f4278c
1 changed files with 572 additions and 155 deletions
|
|
@ -109,16 +109,9 @@ interface UIResource {
|
|||
}
|
||||
}
|
||||
|
||||
interface UIResourceMeta {
|
||||
/**
|
||||
* Content Security Policy configuration
|
||||
*
|
||||
* Servers declare which external origins their UI needs to access.
|
||||
* Hosts use this to enforce appropriate CSP headers.
|
||||
*/
|
||||
csp?: {
|
||||
interface McpUiResourceCsp {
|
||||
/**
|
||||
* Origins for network requests
|
||||
* Origins for network requests (fetch/XHR/WebSocket)
|
||||
*
|
||||
* - Empty or omitted = no external connections (secure default)
|
||||
* - Maps to CSP `connect-src` directive
|
||||
|
|
@ -138,7 +131,24 @@ interface UIResourceMeta {
|
|||
* ["https://cdn.jsdelivr.net", "https://*.cloudflare.com"]
|
||||
*/
|
||||
resourceDomains?: string[],
|
||||
},
|
||||
/**
|
||||
* Origins for nested iframes (frame-src directive).
|
||||
*/
|
||||
frameDomains?: string[],
|
||||
/**
|
||||
* Allowed base URIs for the document (base-uri directive).
|
||||
*/
|
||||
baseUriDomains?: string[],
|
||||
}
|
||||
|
||||
interface UIResourceMeta {
|
||||
/**
|
||||
* Content Security Policy configuration
|
||||
*
|
||||
* Servers declare which external origins their UI needs to access.
|
||||
* Hosts use this to enforce appropriate CSP headers.
|
||||
*/
|
||||
csp?: McpUiResourceCsp,
|
||||
/**
|
||||
* Dedicated origin for widget
|
||||
*
|
||||
|
|
@ -178,8 +188,10 @@ The resource content is returned via `resources/read`:
|
|||
_meta?: {
|
||||
ui?: {
|
||||
csp?: {
|
||||
connectDomains?: string[]; // Origins for fetch/XHR/WebSocket
|
||||
resourceDomains?: string[]; // Origins for images, scripts, etc
|
||||
connectDomains?: string[]; // Origins for network requests (fetch/XHR/WebSocket).
|
||||
resourceDomains?: string[]; // Origins for static resources (scripts, images, styles, fonts).
|
||||
frameDomains?: string[]; // Origins for nested iframes (frame-src directive).
|
||||
baseUriDomains?: string[]; // Allowed base URIs for the document (base-uri directive).
|
||||
};
|
||||
domain?: string;
|
||||
prefersBorder?: boolean;
|
||||
|
|
|
|||
Loading…
Reference in a new issue