T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/svg2png.js:37
- Finding
- Untrusted SVG Content Is Rendered in a Network-Enabled Browser with Chromium Sandboxing Disabled## Vulnerability Details **File Location**: `scripts/svg2png.js`, lines 37-59 **Vulnerability Type**: Unsafe rendering of active SVG content **Risk Level**: High **Vulnerable 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-sandbox` and `--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
- ## Remediation Suggestions 1. Remove `--no-sandbox` and `--disable-setuid-sandbox`. Run Chromium with its standard sandbox enabled. 2. 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. 3. Disable JavaScript before loading the document: ```javascript await page.setJavaScriptEnabled(false); ``` 4. 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()); ``` 5. Sanitize SVG using a maintained XML/SVG sanitizer and an element-and-attribute allowlist. Reject at least: - `script`, `foreignObject`, `iframe`, `object`, and `embed`. - Event-handler attributes such as `onload` and `onclick`. - `javascript:` and remote `http:` or `https:` URLs. - External `href`, `xlink:href`, CSS imports, and external font references. - XML entities and DTD declarations. 6. Apply input-size, SVG-dimension, animation-duration, screenshot-duration, and DPI limits to reduce denial-of-service risk. 7. Put browser cleanup in a `finally` block so Chromium is closed when parsing, rendering, or screenshot creation fails. 8. Treat generated SVG as untrusted even when it originated from an AI model, because article content or prompt injection can influence generated markup.
