T09 · Insecure Skill Coding Practices
- Location
scripts/generate.py:267- Finding
Unescaped Report Data Enables Stored HTML and JavaScript Injection
- Content
View full analysis
{item}" for item in items]) # Prepare context for template context = { "title": data.get("title", "述职报告"), "goal": data.get("goal", ""), "q1_title": data.get("q1", {}).get("title", ""), "q1_subtitle": data.get("q1", {}).get("subtitle", ""), "q1_slogan": data.get("q1", {}).get("slogan", ""), "q1_items": format_list(data.get("q1", {}).get("items", [])), "q2_title": data.get("q2", {}).get("title", ""), "q2_subtitle": data.get("q2", {}).get("subtitle", ""), "q2_slogan": data.get("q2", {}).get("slogan", ""), "q2_items": format_list(data.get("q2", {}).get("items", [])), "q3_title": data.get("q3", {}).get("title", ""), "q3_subtitle": data.get("q3", {}).get("subtitle", ""), "q3_slogan": data.get("q3", {}).get("slogan", ""), "q3_items": format_list(data.get("q3", {}).get("items", [])), "q4_title": data.get("q4", {}).get("title", ""), "q4_subtitle": data.get("q4", {}).get("subtitle", ""), "q4_slogan": data.get("q4", {}).get("slogan", ""), "q4_items": format_list(data.get("q4", {}).get("items", [])), "summary_1": data.get("summary", ["", "", "", ""])[0], "summary_2": data.get("summary", ["", "", "", ""])[1], "summary_3": data.get("summary", ["", "", "", ""])[2], "summary_4": data.get("summary", ["", "", "", ""])[3], } html_content = HTML_TEMPLATE.format(**context) ``` ### Technical Analysis E ...[truncated 3203 chars]- Remediation
View remediation
{escape_text(item)}" for item in items) ``` 2. Escape all scalar fields, including the document title, goal, quadrant titles, subtitles, slogans, and summary values: ```python context = { "title": escape_text(data.get("title", "Default Report")), "goal": escape_text(data.get("goal", "")), # Apply escape_text to every remaining scalar field. } ``` 3. Prefer a template engine with automatic HTML escaping, such as Jinja2 configured with `select_autoescape`, rather than using unrestricted `str.format` interpolation. 4. Validate the complete JSON schema before rendering: - Require the top-level value to be an object. - Require `q1` through `q4` to be objects. - Require text fields to be strings. - Require each `items` value and `summary` to be arrays of strings. - Require exactly four summary entries or handle missing entries safely. - Enforce reasonable length limits to reduce rendering and resource-exhaustion risks. 5. Add a restrictive Content Security Policy to the generated document as defense in depth: ```html ``` 6. Render untrusted reports in a sandboxed, isolated browser context with network access disabled. Do not rely on browser isolation as a substitute for output encoding. 7. Add regression tests containing paylo ...[truncated 141 chars]
