T09 · Insecure Skill Coding Practices
- Location
scripts/budget-report.sh:91- Finding
Unescaped Event Data Enables Active HTML Injection in Playwright Reports
- Content
View full analysis
0 else 0 bar_color = "#22c55e" if pct <= 80 else ("#f59e0b" if pct <= 100 else "#ef4444") html_rows += f"""""" html = f""" body {{ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; background: #0f172a; color: #e2e8f0; padding: 32px; margin: 0; width: 720px; }} h1 {{ color: #f8fafc; margin-bottom: 4px; font-size: 24px; }} .subtitle {{ color: #94a3b8; margin-bottom: 24px; font-size: 14px; }} .summary {{ display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 16px; margin-bottom: 32px; }} .card {{ background: #1e293b; border-radius: 12px; padding: 16px; text-align: center; }} .card .label {{ color: #94a3b8; font-size: 12px; text-transform: uppercase; letter-spacing: 1px; }} .card .value {{ font-size: 28px; font-weight: 700; margin-to ...[truncated 3774 chars]{name} \${spent:,.2f} / \${allocated:,.2f} ({pct:.0f}%)- Remediation
View remediation
{safe_category_name}💰 {safe_event_name} — Budget Report
``` 2. Prefer a template engine configured with automatic HTML escaping rather than manually assembling HTML with f-strings. 3. Disable JavaScript because the report does not require it: ```python browser = p.chromium.launch() context = browser.new_context(java_script_enabled=False) page = context.new_page() ``` 4. Block all network requests during local report rendering: ```python def block_network(route): if route.request.url.startswith("file://"): route.continue_() else: route.abort() page.route("**/*", block_network) ``` 5. Validate input types before numeric formatting. Reject strings, non-finite values, and unexpected structures in budget fields. 6. Delete temporary HTML in a `finally` block so failed rendering does not leave active injected content on disk. 7. Add regression tests using event and category names containing: - HTML elements - `
