T09 · Insecure Skill Coding Practices
- Location
scripts/render-html-pptx.js:54- Finding
Untrusted Slide Content Is Inserted into Executable HTML Without Escaping
- Content
View full analysis
${slide.kicker ? `${escHtml(slide.kicker)}
` : ''}${slide.title || ''}
${slide.subtitle ? `${escHtml(slide.subtitle)}
` : ''} `; } ``` Other affected code includes: ```javascript${slide.title || 'Contents'}
``` ```javascript${slide.title || ''}
``` ```javascript${slide.quote || ''}
``` ```javascript${slide.title || 'Comparison'}
``` The generated document is subsequently opened as an active HTML document in headless Chromium: ```javascript await page.goto(`file://${path.resolve(htmlPath)}`, { waitUntil: 'networkidle' }); ``` ### Technical Analysis The renderer uses `escHtml()` for many fields but omits it for several `title` and `quote` interpolations. These fields originate from the supplied JSON or YAML content and are inserted directly into an HTML template. Because the generated HTML is loaded into Chromium with JavaScript enabled and without a restrictive Content Security Policy, injected elements and event handlers can execute. For example, an attacker-controlled title could contain: ```html- Remediation
View remediation
${escHtml(slide.title || '')} ``` ```javascript${escHtml(slide.quote || '')}
``` 3. If selected fields intentionally support formatting, process them with a proven allowlist-based HTML sanitizer. Permit only necessary formatting elements such as `strong`, `em`, and `span` with tightly restricted classes. Remove: - Script elements. - Event-handler attributes. - Frames and embedded objects. - URL-bearing attributes unless explicitly required. - Inline styles unless sanitized. 4. Define a clear schema distinguishing plain-text fields from sanitized rich-text fields. 5. Add a restrictive Content Security Policy to the generated HTML, for example disabling scripts, plugins, frames, and unexpected connections. 6. Disable JavaScript in the Playwright browser context if the conversion library permits it. If JavaScript is required for conversion, keep application scripts fixed and block inline event handlers through CSP. 7. Intercept Playwright requests and deny all network access unless an explicitly approved resource is required. 8. Add regression tests using payloads in every slide field and verify that they appear as inert text and do not create executable DOM nodes. ]]>
