T09 · Insecure Skill Coding Practices
- Location
scripts/render_pdf.py:86- Finding
Unrestricted Active Content and Remote Resource Loading During HTML-to-PDF Rendering
- Content
View full analysis
None: chrome = chrome_path or _find_chrome() if not chrome or not chrome.exists(): raise RuntimeError( "Chrome not found. Install Google Chrome or put chrome.exe on PATH." ) in_path = _ensure_html_has_page_size(in_path, paper) out_pdf.parent.mkdir(parents=True, exist_ok=True) file_url = in_path.resolve().as_uri() cmd = [ str(chrome), "--headless=new", "--disable-gpu", "--no-first-run", "--no-default-browser-check", "--disable-extensions", f"--print-to-pdf={out_pdf.resolve()}", "--no-pdf-header-footer", "--print-to-pdf-no-header", file_url, ] _run(cmd) ``` The bundled templates demonstrate that network resources are loaded during rendering: ```html
```
### Technical Analysis
The documented compile-only workflow accepts an existing HTML file and passes its local `file://` URL directly to headless Chrome. The Chrome invocation does not disable JavaScript, block outb
...[truncated 2805 chars]- Remediation
View remediation
`, ``, `<object>`, `<embed>`, active SVG content, event-handler attributes, `javascript:` URLs, and remote resource URLs. - Use a maintained allowlist-based HTML sanitizer. - Validate both HTML attributes and CSS constructs capable of loading external resources. 3. **Apply a restrictive Content Security Policy** - Inject a policy such as `default-src 'none'` and selectively permit only required local resources. - Set `script-src 'none'`, `connect-src 'none'`, `frame-src 'none'`, and `object-src 'none'`. - Restrict images, styles, and fonts to locally controlled files. 4. **Vendor all template assets locally** - Store fonts, icons, and placeholder images inside the Skill package. - Replace Google Fonts, Cloudflare CDN, and Aliyun OSS references with local relative paths. - If an external resource cannot be removed, pin and verify its expected cryptographic hash before use. 5. **Harden the renderer** - Execute Chrome as an unprivileged, dedicated user inside an ephemeral sandbox. - Limit CPU, memory, execution time, process count, and output size. - Use a temporary profile directory that is deleted after every render. - Keep Chrome's sandbox enabled and avoid adding flags such as `--no-sandbox`. 6. **Require explicit trust decisions** - Treat user-provided HTML as untrusted by default. - Require explicit confirmation before rendering documents that contain remote URLs or active content. - Log blocked resources without exposing resume contents or other personal information. ] ...[truncated 2 chars]
