import { describe, expect, it, vi } from "vitest"; import { SAFE_CSP_SOURCE, approveCspSources, approveSandboxPermissions, buildSandboxCspPolicy, escapeHtmlAttr, wrapSandboxedHtml, } from "./sandbox-csp"; describe("SAFE_CSP_SOURCE", () => { it.each([ "*", "https://api.example.com", "https://api.example.com:8443", "https://api.example.com/path/seg", "wss://realtime.service.com", "*.example.com", "https://*.cloudflare.com", "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); }); it.each([ "https://a.com; script-src *", 'https://a.com" onload=', "https://a.com>", "app`; const wrapped = wrapSandboxedHtml(evil, "default-src 'none'"); // The first in the output is OURS; the untrusted token only // appears after . const ourHead = wrapped.indexOf(""); const body = wrapped.indexOf(""); const evilHead = wrapped.indexOf("", ourHead + 1); expect(ourHead).toBeLessThan(body); expect(evilHead).toBeGreaterThan(body); }); it("does not introduce a host-authored