T09 · Insecure Skill Coding Practices
- Location
weather_digest.py:146- Finding
Stored HTML Injection Through Unescaped Dynamic Weather Data
- Content
View full analysis
Expires {expiry}" if expiry else "" instructions_html = ( f"{instructions}" if instructions else "" ) blocks.append( f"" ) return "".join(blocks) ``` ```python city_meta = "" if report.get("city") and report.get("state"): city_meta = f"{event}" f"{severity}{expiry_html}" f"{headline}{instructions_html}Nearest location: {report['city']}, {report['state']}" summary_li = "".join( f"- {line.replace('**', '')}
" for line in report["summary_lines"] ) alerts_html = format_alerts_html(report["alerts"]) cards.append( f" " ) ``` ### Technical Analysis The HTML renderer inserts dynamic values directly into HTML without context-appropriate escaping. The affected values include: - The locally configured location display name. - City and state values returned by the weather API. - Forecast summary values returned by the weather API. - Alert event, severity, headline, expiration, and instruction values. Removing Markdown markers with `replace('**', '')` does not sanitize HTML. Trimming alert text also does not remove tags or event-handler attributes. Consequently, a value such as `{report['display_name']}
{city_meta}" f"Outlook
- {summary_li}
Active Alerts
{alerts_html}` is preserved as active HTML ...[truncated 1598 chars]
- Remediation
View remediation
``` The generated document should contain escaped text such as `<img ...>`, not an active element. 6. If arbitrary markup is intentionally supported in the future, sanitize it with a maintained allowlist-based HTML sanitizer rather than relying on string replacement. ]]>
