T09 · Insecure Skill Coding Practices
- Location
handler.py:187- Finding
Untrusted Input Allows Markdown Report Injection
- Content
View full analysis
str: if inputs is None: return "" if isinstance(inputs, str): return inputs.strip() if isinstance(inputs, dict): parts: List[str] = [] for key, value in inputs.items(): if value in (None, "", [], {}, ()): # type: ignore[comparison-overlap] continue if isinstance(value, (list, tuple, set)): rendered = ", ".join(str(item) for item in value) else: rendered = str(value) parts.append(f"{key}: {rendered}") return " | ".join(parts) if isinstance(inputs, (list, tuple, set)): return " | ".join(str(item) for item in inputs) try: return json.dumps(inputs, ensure_ascii=False, sort_keys=True) except TypeError: return str(inputs) ``` The resulting text is inserted into the Markdown report without escaping: ```python lines.append(f"**Input snapshot:** {self.text or 'No structured logistics brief was provided, so this report uses default ecommerce fulfillment assumptions.'}") ``` ### Technical Analysis The `handle()` entry point accepts untrusted input and passes it to `ShippingCostOptimizer`. `_normalize_inputs()` preserves embedded line breaks and Markdown control syntax in strings, dictionary keys, dictionary values, and collection elements. The normalized value is then interpolated directly into a Markdown document. An attacker can therefore inject headings, links, images, tables, blockquotes, or fabricated report sections. Because the injected content appears inside a generated optimization report, users or downstream agents may mistake attacker-controlled statements for trusted recommendations. This issue does not provide operating-system c ...[truncated 1811 chars]- Remediation
View remediation
str: value = value.replace("\r", " ").replace("\n", " ") for char in ("\\", "`", "*", "_", "{", "}", "[", "]", "<", ">", "#", "|"): value = value.replace(char, "\\" + char) return value snapshot = _escape_markdown_inline( self.text or "No structured logistics brief was provided, so this report uses default ecommerce fulfillment assumptions." ) lines.append(f"**Input snapshot:** {snapshot}") ``` Escaping order and renderer behavior should be verified with tests. For stronger isolation, represent user input as structured data rather than concatenating it into trusted Markdown prose. ]]>
