T09 · Insecure Skill Coding Practices
- Location
scripts/generate_report.py:751- Finding
Stored HTML and Script Injection Through Session-Derived Report Data
- Content
View full analysis
{s[:100]}' for s in cx.get('searches', [])[:8] )} ``` ```python dt_items = "".join( f'{tn}{cnt}' for tn, cnt in list(kc["domain_tools"].items())[:12] ) ``` ### Technical Analysis The report generator treats values extracted from local AI session records as trusted HTML. Codex web-search queries and Kimi tool names are inserted directly into the generated document without HTML escaping. These records may contain attacker-influenced content. For example, a malicious search query could contain: ```html``` When this value is interpolated into the report, the browser interprets it as markup instead of plain text. Truncating the value does not provide security because compact event-handler payloads can fit within the imposed limits. The `js_safe()` helper elsewhere in the file only serializes values for JavaScript contexts and replaces closing-script sequences. It does not protect values inserted directly into HTML contexts. The generated document also has no Content Security Policy to prevent inline event handlers or unauthorized outbound requests. ### Attack Path 1. An attacker causes a crafted value containing HTML markup to be recorded as a Codex web-search query or Kimi tool name. 2. The value is stored in a local Codex or Kimi session record. 3. The user invokes `generate_report.py`. 4. The script reads the malicious value from the session record. 5. The value is interpolated directly into ...[truncated 1112 chars]
- Remediation
View remediation
{escape(str(s), quote=True)}' for s in cx.get("searches", [])[:8] ) dt_items = "".join( f"{escape(str(tn), quote=True)}{int(cnt)}" for tn, cnt in list(kc["domain_tools"].items())[:12] ) ``` 3. Prefer keeping dynamic values in safely serialized JSON and rendering them with DOM APIs that use `textContent`, rather than constructing HTML strings. 4. Audit every formatted HTML string for other session-derived values. Escaping must match the destination context: HTML text, HTML attribute, JavaScript string, and URL contexts require different handling. 5. Add a restrictive Content Security Policy. After removing inline scripts and event handlers, use a policy similar to: ```html ``` 6. Add regression tests with payloads containing `` to verify that all values appear only as text. ]]>
