T09 · Insecure Skill Coding Practices
- Location
scripts/svg2png.js:37- Finding
Untrusted SVG Content Is Rendered in a Network-Enabled Browser with Chromium Sandboxing Disabled
- Content
View full analysis
Vulnerability Details
File Location:
scripts/svg2png.js, lines 37-59
Vulnerability Type: Unsafe rendering of active SVG content
Risk Level: HighVulnerable Code:
javascript const browser = await puppeteer.launch({ headless: "new", args: [ "--no-sandbox", "--disable-setuid-sandbox", "--disable-dev-shm-usage", "--disable-accelerated-2d-canvas", "--no-first-run", "--no-zygote", "--disable-gpu", "--disable-extensions", "--disable-background-timer-throttling", "--disable-backgrounding-occluded-windows", "--disable-renderer-backgrounding", "--disable-features=TranslateUI", "--disable-ipc-flooding-protection", "--enable-features=NetworkService,NetworkServiceInProcess" ], executablePath: findChrome(), }); const page = await browser.newPage(); await page.setContent(svgContent, { waitUntil: "networkidle0" });Technical Analysis
The conversion command accepts a caller-selected SVG file, reads its complete contents, and passes those contents directly to Chromium using
page.setContent(). No validation or sanitization is performed before rendering.SVG is not necessarily passive image data. It can contain scripts, event handlers, external image references, embedded HTML through
foreignObject, resource URLs, and computationally expensive animation or filter content. JavaScript remains enabled on the Puppeteer page, and the script does not install request interception to deny outbound or internal-network requests.The Chromium process is also launched with both
--no-sandboxand--disable-setuid-sandbox. These options remove an important isolation boundary intended to contain a compromised renderer. Although malicious SVG content alone does not automatically grant native code execution, successful exploitation of a Chromium vulnerability would have a substantially g ...[truncated 1838 chars]- Remediation
View remediation
Remediation Suggestions
- Remove
--no-sandboxand--disable-setuid-sandbox. Run Chromium with its standard sandbox enabled. - Render inside a dedicated, unprivileged container or operating-system account with:
- A read-only filesystem where possible.
- No access to secrets or user data.
- Strict CPU, memory, process, and execution-time limits.
- No unnecessary Linux capabilities.
- Disable JavaScript before loading the document:
javascript await page.setJavaScriptEnabled(false); - Enable request interception before calling
page.setContent()and reject every network request that is not explicitly required:javascript await page.setRequestInterception(true); page.on("request", request => request.abort()); - Sanitize SVG using a maintained XML/SVG sanitizer and an element-and-attribute allowlist. Reject at least:
script,foreignObject,iframe,object, andembed.- Event-handler attributes such as
onloadandonclick. javascript:and remotehttp:orhttps:URLs.- External
href,xlink:href, CSS imports, and external font references. - XML entities and DTD declarations.
- Apply input-size, SVG-dimension, animation-duration, screenshot-duration, and DPI limits to reduce denial-of-service risk.
- Put browser cleanup in a
finallyblock so Chromium is closed when parsing, rendering, or screenshot creation fails. - Treat generated SVG as untrusted even when it originated from an AI model, because article content or prompt injection can influence generated markup.
- Remove
