T09 · Insecure Skill Coding Practices
- Location
weather_digest.py:135- Finding
Unescaped Dynamic Data in Generated HTML
- Content
View full analysis
str: if not alerts: return "No active alerts" blocks = [] for alert in alerts: event = alert.get("event") or "Alert" severity = alert.get("severity") or "Unknown" expiry = _format_expiration(alert.get("expires")) headline = alert.get("headline") or "Details forthcoming" instructions = _trim_text(alert.get("instructions"), limit=220) expiry_html = f"Expires {expiry}" if expiry else "" instructions_html = ( f"{instructions}" if instructions else "" ) blocks.append( f"" ) return "".join(blocks) ``` ```python def build_html(reports: list[dict], theme: str = "midnight") -> str: today = dt.datetime.now().strftime("%A, %B %d %Y") cards = [] for report in reports: 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"{report['display_name']}
{city_meta}" f"Outlook
- {summary_li}
- Remediation
View remediation
{escape(str(line.replace('**', '')), quote=True)}" for line in report["summary_lines"] ) ``` 3. Prefer a template engine with automatic escaping enabled instead of constructing HTML through f-strings. 4. Validate the configuration schema and enforce expected types and reasonable length limits for names and coordinates. 5. Add regression tests covering `<`, `>`, `&`, quotes, malformed tags, event-handler attributes, and script-like payloads. 6. Apply the same correction to both copies of `weather_digest.py` or remove the duplicate implementation to prevent future security fixes from diverging. ]]>
