T09 · Insecure Skill Coding Practices
- Location
assets/infograph_template.html:6- Finding
Unnecessary External Font Request During Local Rendering
- Content
View full analysis
@import url('https://fonts.googleapis.com/css2?family=DM+Serif+Display&family=DM+Sans:wght@400;500;700&display=swap'); ``` The template is rendered by Playwright as follows: ```javascript const fileUrl = 'file://' + path.resolve(htmlPath); await page.goto(fileUrl, { waitUntil: 'networkidle' }); await page.waitForTimeout(500); ``` ### Technical Analysis The infographic template imports fonts from Google Fonts whenever Chromium renders the generated HTML. Although the primary input document is loaded through a local `file://` URL, the browser retains unrestricted network access. Consequently, a nominally local content-to-PNG operation generates an outbound request to Google. The remote request is not required for the Skill's core functionality because the template already declares fallback system fonts. This behavior exceeds the minimum privileges needed to render a PNG. The request can disclose the host's public IP address, request timing, browser request headers, and the fact that the Skill is being used. It also makes output generation dependent on an external, mutable service. ### Attack Path 1. A user invokes the Skill in infographic mode. 2. The Skill generates HTML from `assets/infograph_template.html`. 3. `scripts/capture.js` opens the resulting local HTML document in Chromium. 4. Chromium evaluates the CSS `@import`. 5. Chromium sends an outbound request to `fonts.googleapis.com`. 6. Google or an intermediary can observe the request metadata, and rendering may block or change depending on the remote response. ### Impact Assessment This issue does not grant local code execution or elevated operating-system privileges. Its scope is network-level privacy leakage and loss of determinis ...[truncated 343 chars]- Remediation
View remediation
{ const url = new URL(route.request().url()); if (url.protocol === 'file:' || url.protocol === 'data:') { await route.continue(); } else { await route.abort(); } }); ``` 5. Register request interception before calling `page.goto`. 6. If remote assets are explicitly required in a future feature, use a documented hostname allowlist and require user consent. 7. Add an automated test that fails when generated templates attempt an HTTP or HTTPS request. ]]>
