T09 · Insecure Skill Coding Practices
- Location
scripts/render_long_image.py:25- Finding
Untrusted HTML Executes with Unrestricted Browser Networking
- Content
View full analysis
None: with sync_playwright() as p: browser = p.chromium.launch() page = browser.new_page( viewport={"width": width, "height": 1000}, device_scale_factor=scale, ) page.goto(html_path.resolve().as_uri(), wait_until="networkidle") page.screenshot(path=str(png_path), full_page=True) browser.close() ``` The renderer accepts HTML from a file, an inline command-line value, or standard input: ```python def read_input(value: str | None) -> tuple[str, Path | None]: if value is None: return sys.stdin.read(), None candidate = Path(value) if candidate.exists() and candidate.is_file(): return candidate.read_text(encoding="utf-8"), candidate return value, None ``` ### Technical Analysis The supplied HTML is opened in a JavaScript-capable Chromium instance. The renderer does not disable JavaScript, intercept network requests, enforce a URL allowlist, inject a restrictive Content Security Policy, or isolate the browser from loopback and private network addresses. Consequently, attacker-controlled HTML can contain active elements such as: ```html ``` It can also initiate requests through images, stylesheets, frames, or scripts without requiring JavaScript: ```html``` Browser same-origin controls may prevent reading many cross-origin responses, but they do not prevent sending requests. Depending on ...[truncated 1630 chars]
- Remediation
View remediation
``` 5. Separate trusted and untrusted rendering modes. Any mode that enables JavaScript or remote resources should require an explicit opt-in and should execute inside a network-isolated, disposable sandbox. 6. Do not place secrets or sensitive environment information in the rendered DOM unless active content and outbound communication have been reliably disabled. ]]>
