T09 · Insecure Skill Coding Practices
- Location
scripts/generate_pdf.py:112- Finding
Unescaped Spreadsheet Values Allow Active HTML Injection During PDF Generation
- Content
View full analysis
{handler} {h_total} {completed} {pending} {very_sat} {avg_sat:.1f} {avg_time:.0f}分钟 """ type_rows = "" for t, c in df['工单类型'].value_counts().items(): type_rows += f"{t}{c}{c/total*100:.1f}%" status_rows = "" for s, c in df['工单状态'].value_counts().items(): status_rows += f"{s}{c}{c/total*100:.1f}%" sat_rows = "" for opt, cnt in df['满意度选项'].value_counts().items(): sat_rows += f"{opt}{cnt}{cnt/total*100:.1f}%" issue_rows = "" for issue, cnt in issue_counts.most_common(15): issue_rows += f"{issue}{cnt}{cnt/total*100:.1f}%" module_rows = "" for module, cnt in df['模块'].value_counts().head(10).items(): module_rows += f"{module}{cnt}{cnt/total*100:.1f}%" menu_rows = "" for menu, cnt in df['菜单'].value_counts().head(10).items(): menu_rows += f"{menu}{cnt}{cnt/total*100:.1f}%" group_rows = "" for group, cnt in df['处理工作组'].value_counts().head(10).items(): group_rows += f"{group}{cnt}{cnt/total*100:.1f}%" ``` The resulting document is subsequently loaded into a JavaScript-capable browser: ```python html_path = "/tmp/lingji_report.html" with open(html_path, "w", encoding="utf-8") as f: f.write(html_content) with sync_playwright() as p: browser = p.chromium.launch() page = browser.new_page() page.goto(f"file://{html_path}") page.pdf( path=output_path, format="A4", margin={"top": "15mm", "bottom": "15mm", "left": "15m ...[truncated 2398 chars]- Remediation
View remediation
{html_text(handler)}..." type_rows += ( f"{html_text(t)}" f"{c}{c / total * 100:.1f}%" ) ``` 2. Prefer a template engine configured with automatic escaping rather than assembling HTML through string concatenation. 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 network requests during rendering unless a specific resource is explicitly required: ```python page.route( "**/*", lambda route: route.continue_() if route.request.url.startswith("file://") else route.abort() ) ``` 5. Validate workbook fields against expected types and reasonable length limits before report generation. 6. Add regression tests containing HTML metacharacters and malicious markup, verifying that they appear as literal text and do not generate requests or alter report structure. ]]>
