T09 · Insecure Skill Coding Practices
- Location
scripts/failure_forensics.py:323- Finding
Unescaped Log Data Permits Markdown Report Injection
- Content
View full analysis
80 else (call.error or "") timeline_rows.append(f"| {i} | {ts} | `{call.tool}` | {outcome} | {err} |") ``` ```python return POST_MORTEM_TEMPLATE.format( title=title, date=now, author=author, primary_category=primary_category, total_calls=summary["total_calls"], failed_calls=summary["failed_calls"], first_failure_tool=summary["first_failure_tool"] or "N/A", first_failure_error=(summary["first_failure_error"] or "N/A")[:200], first_failure_category=summary["first_failure_category"] or "uncategorized", timeline_table=timeline_table, ) ``` ### Technical Analysis The report generator directly interpolates data from analyzed logs into Markdown table cells, inline-code spans, headings, and template fields. The affected values include the tool name, error message, report title, and author. These values are not escaped or normalized before insertion. An attacker-controlled error message or tool name can c ...[truncated 2041 chars]- Remediation
View remediation
str: text = str(value) text = text.replace("\\", "\\\\") text = text.replace("|", "\\|") text = text.replace("\r", " ").replace("\n", " ") text = text.replace("`", "\\`") return text ``` 3. Apply the helper to every untrusted value inserted into timeline tables, including `call.tool`, `call.error`, and any derived category text. 4. Validate and sanitize report metadata such as `title` and `author`. Restrict them to a single line and escape Markdown metacharacters before template interpolation. 5. If raw HTML is unnecessary, strip or encode HTML delimiters before writing the report. Where possible, configure the downstream renderer to disable raw HTML. 6. Add regression tests covering: - Pipe characters such as `| forged cell |` - Embedded backticks - Carriage returns and newlines - Markdown headings and links - Raw HTML tags - Combined payloads that attempt to escape both inline-code and table contexts 7. Verify remediation by generating both timeline and post-mortem output from adversarial JSONL fixtures and confirming that all input remains inert text within its intended field. ]]>
