Follow-up from #359.
The inline HTML preview injects its CSP as a <meta http-equiv="Content-Security-Policy"> tag by regex-matching the first <head> (app/src/renderer/files/html-preview.ts). A crafted HTML file can dodge that injection -- e.g. a <head> literal inside an HTML comment or an attribute value before the real <head> makes the regex match there, so the meta lands in an inert position and the actual document parses with no CSP.
Impact is bounded: the iframe is opaque-origin (sandbox="allow-scripts", no allow-same-origin) and the orbit-artifact:// handler sets no CORS headers, so a script still can't read other cwd files. But with the CSP gone, a malicious report could exfiltrate its own rendered content to the network -- which is exactly what the CSP is meant to prevent.
Fix direction: serve the preview document through a protocol handler that sets Content-Security-Policy as a real response header, instead of a blob: URL with an injected <meta>. A response-header CSP can't be repositioned by document content, so the boundary holds regardless of how adversarial the HTML is.
(Flagged during review of #359.)
Follow-up from #359.
The inline HTML preview injects its CSP as a
<meta http-equiv="Content-Security-Policy">tag by regex-matching the first<head>(app/src/renderer/files/html-preview.ts). A crafted HTML file can dodge that injection -- e.g. a<head>literal inside an HTML comment or an attribute value before the real<head>makes the regex match there, so the meta lands in an inert position and the actual document parses with no CSP.Impact is bounded: the iframe is opaque-origin (
sandbox="allow-scripts", noallow-same-origin) and theorbit-artifact://handler sets no CORS headers, so a script still can't read other cwd files. But with the CSP gone, a malicious report could exfiltrate its own rendered content to the network -- which is exactly what the CSP is meant to prevent.Fix direction: serve the preview document through a protocol handler that sets
Content-Security-Policyas a real response header, instead of ablob:URL with an injected<meta>. A response-header CSP can't be repositioned by document content, so the boundary holds regardless of how adversarial the HTML is.(Flagged during review of #359.)