13. Security

Concern Measure SRS
Webview code CSP: default-src 'none'; script-src 'nonce-<n>' 'wasm-unsafe-eval'; worker-src <cspSource>; style-src <cspSource>; img-src <cspSource> blob: data:; font-src <cspSource>; connect-src <cspSource>; Inline styles set through the CSSOM (element.style[...]) are not affected by style-src, so no 'unsafe-inline' is needed. 'wasm-unsafe-eval' allows compiling harfbuzz.wasm and icu_segmenter.wasm and nothing else. worker-src admits the render worker (ADR-10) from the extension’s own resources only, never blob:. No remote resources. NFR-4
Webview resources localResourceRoots: the extension’s media/, the document’s assets folder. Font bytes from OS and workspace folders go through font.get, so those folders are never exposed. NFR-4
Scripts QuickJS in WASM: no host objects but the prelude’s functions; every write is a validated registry command; limits (§8.1). The worker runs with resourceLimits as a second fence. CMD-11
Bridge Registry folder 0700, entries 0600, sockets in that folder (named pipes on Windows with a random name), a 32-byte random token per window checked on every request, requests for files not open in that window answered handled: false. NFR-4
Asset server (§9.6) Bound to 127.0.0.1 only; Host must equal 127.0.0.1:<port>; any request carrying an Origin header is refused (403); 128-bit single-use tokens with a 10-minute lifetime; 10 MB body cap; GET and upload-slot PUT only; no-store, nosniff; rate-limited on bad tokens; runs only while the extension host or ud mcp runs, and a one-shot CLI never starts it (url: null). NFR-4, CMD-4, CMD-5
Fonts in the repository font.embed copies a face into the assets folder only when its OS/2 fsType permits embedding (§6.2); restricted faces are refused with a warning, so a commercial OS font is not committed to git by accident. —
SVG import Parsed by our own XML parser in src/core/svg/ (no DOM), converted to nodes through an allowlist of elements and attributes. Dropped: script, foreignObject, event handler attributes, hrefs that are not #fragment or `data:image/(png jpeg
Text from files Names, text content, plugin data and comments reach the page as data and are set with textContent; the page contract forbids innerHTML. UI-3
Secrets Figma tokens (EXP-5) and licence keys in SecretStorage; the CLI licence ticket is a signed public document, mode 0600. NFR-4
AI Claude Code with an allowed-tool list, the user’s own account, no SoftForge keys, no design data to SoftForge (AI-13, AI-14). AI-13, AI-14
Imports HTML import (EXP-6) runs the page in a separate headless browser process, never in the webview. —