T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/parse.py:42
- Finding
- Attacker-Controlled Log Content Can Break Out of Markdown Code Fences## Vulnerability Details **File Location**: `scripts/parse.py:42-49` **Vulnerability Type**: Improper neutralization of untrusted content in generated Markdown **Risk Level**: Medium ### Vulnerable Code ```python def to_markdown_alerts(rules): lines = ["# Alert Rules\n"] for r in rules: lines.append(f"## {r['name']} (`{r['type']}`)\n") lines.append(f"- **Severity:** {r['severity']}") lines.append(f"- **Occurrences:** {r['count']}") lines.append(f"- **Regex:** ````{r['pattern']}````") lines.append(f"- **Samples:**") for s in r["top_samples"]: lines.append(f" ```\n {s}\n ```") ``` ### Technical Analysis Log samples are attacker-controlled data and are inserted verbatim into Markdown code fences. The implementation neither escapes backtick sequences nor selects a fence longer than those appearing in the sample. The parser separates records only on the line-feed character: ```python lines = [l.strip() for l in log_text.split("\n") if l.strip()] ``` Consequently, a record containing carriage-return-only separators can remain a single Python string while being interpreted as multiple lines by Markdown processors that normalize carriage returns. Such content can include a valid closing fence followed by attacker-controlled Markdown. Even when the generated report is not rendered, passing it to another AI Agent without preserving the trust boundary can turn injected report text into indirect prompt-injection content. The parser itself does not execute the injected content. ### Attack Path 1. An attacker causes a server log to contain a record with a recognized term such as `error`. 2. The record uses carriage-return-only separators and includes a closing Markdown fence followed by attacker-controlled Markdown or instructions. 3. `extract_patterns()` retains the record as a sample because `split("\n")` does not divide it at carriage ret ...[truncated 787 chars]
- Remediation
- ## Remediation Suggestions - Normalize all supported line endings before parsing, for example with `splitlines()`. - Escape or replace backtick runs in untrusted samples before Markdown serialization. - Alternatively, calculate the longest backtick run in each sample and use a strictly longer fence. - Consider encoding samples as indented code blocks or structured JSON rather than interpolating them into Markdown. - Clearly label all extracted samples as untrusted input. - Do not pass generated reports to an AI Agent as trusted instructions; isolate samples in a data-only channel where available. - Add tests covering triple backticks, carriage-return-only logs, mixed line endings, Markdown links, and Agent-instruction-like content.
