T09 · Insecure Skill Coding Practices
- Location
scripts/generate_card.py:691- Finding
Unescaped User Input Allows Active HTML and JavaScript Execution
- Content
View full analysis
{desc}' if desc else "" items_html += f"""""" return tpl.safe_substitute( bg_color=data.get("bg_color", "#F5F0E8"), accent_color=data.get("accent_color", "#8B6F47"), brand_color=data.get("brand_color", "#5C4A35"), title_color=data.get("title_color", "#1A1209"), text_secondary=data.get("text_secondary", "#6B5D4F"), text_muted=data.get("text_muted", "#A89880"), divider_color=data.get("divider_color", "#D4C4B0"), num_bg=data.get("num_bg", "#D4C4B0"), num_color=data.get("num_color", "#5C4A35"), accent_circle1=data.get("accent_circle1", "#C4A882"), accent_circle2=data.get("accent_circle2", "#8B6F47"), brand=data.get("brand", "BRAND"), issue_no=data.get("issue_no", "Vol.01"), kicker=data.get("kicker", ""), title=data.get("title", "标题").replace("\n", "{i:02d}{title}{desc_html}
"), subtitle=data.get("subtitle", ""), list_label=data.get("list_label", "核心要点"), list_items_html=items_html, footer_brand=data.get("footer_brand", data.get("brand", "BRAND")), footer_tagline=data.get("footer_tagline", ""), ) ``` The generated document is subsequently loaded into an active Chromium page: ```python with sync_playwright() as p: browser = p.chromium.launch(headless=True) page = browser.ne ...[truncated 2931 chars]- Remediation
View remediation
")` before escaping. Escape first and then add the controlled line-break markup: ```python safe_title = "
".join( escape(part, quote=True) for part in str(raw_title).splitlines() ) ``` 3. Apply context-specific validation: - Escape HTML text and attribute values. - Restrict class names to explicit allowlists. - Parse and validate colors rather than inserting arbitrary CSS. - Reject unsupported URL schemes. - Do not use one generic sanitizer for HTML, CSS, and URL contexts. 4. Avoid supporting arbitrary raw HTML. If limited formatting is a product requirement, use a mature allowlist sanitizer and permit only necessary formatting elements without event handlers, scripts, frames, forms, or active URLs. 5. Disable JavaScript during screenshot generation if the templates do not require it: ```python browser = p.chromium.launch(headless=True, java_script_enabled=False) ``` Alternatively, set `java_script_enabled=False` on the browser context where supported. 6. Add Playwright request interception and reject all network traffic unless a resource has been explicitly approved. 7. Add regression tests covering script elements, event-handler attributes, malformed tags, attribute breakouts, CSS breakouts, iframes, and remote resource elements. ]]>
