T09 · Insecure Skill Coding Practices
- Location
scripts/analyze.py:20- Finding
Untrusted Terminal and Markdown Output Injection
- Content
View full analysis
Vulnerability Details
File Location:
scripts/analyze.py, lines 20-23 and 43-48
Vulnerability Type: Unsanitized rendering of attacker-controlled structured input
Risk Level: LowVulnerable Code
python payload = read_stdin_json() context = payload.get("shopping_context") or {} report = payload.get("decision_report") or {} query = context.get("query") or {} candidates = context.get("candidates") or []python for candidate in candidates: price = ((candidate.get("price") or {}).get("final_price")) source = candidate.get("source") or "unknown" relation = ((candidate.get("comparison") or {}).get("relation")) or "same_item" line = f"- {candidate.get('id')}: {candidate.get('title')}"The constructed line is subsequently printed without sanitization:
python print(line)Other attacker-controlled fields, including category, scenario, priorities, pitfalls, alternative directions, candidate identifiers, and the final decision, are rendered using the same unsafe pattern.
Technical Analysis
analyze.pyreads arbitrary JSON from standard input and directly renders values from that JSON into terminal or Markdown output. Although the project includesschema.json, the script does not validate its input against that schema. It also does not enforce string length limits, verify expected scalar and collection types, escape Markdown syntax, or remove terminal control characters.An attacker can place ANSI escape sequences in a candidate title or another displayed field to manipulate terminal presentation. In a Markdown consumer, crafted headings, links, images, or list syntax can inject misleading sections into the generated report. This is an output-injection issue rather than command injection: the reviewed implementation does not pass these values to a shell, interpreter, or network client.
Attack Path
- An attacker prepares a JSON payload containing a malicious candidate title or report field.
- The ...[truncated 960 chars]
- Remediation
View remediation
Remediation Suggestions
- Validate every input to
analyze.pyagainstschema.jsonbefore rendering it. - Enforce expected types and explicit maximum lengths for titles, identifiers, categories, priorities, decisions, pitfalls, and alternative directions.
- Remove unsafe C0 and C1 terminal control characters, including escape characters, while retaining only explicitly permitted whitespace.
- Escape Markdown metacharacters when output is intended to be Markdown, especially in user-controlled titles and free-text fields.
- Reject unexpected nested objects or arrays instead of implicitly converting or joining them.
- Keep terminal-safe text rendering separate from Markdown rendering so each output format can apply appropriate encoding.
- Add regression tests using ANSI escape sequences, embedded headings, deceptive links, multiline values, and oversized strings.
- Validate every input to
