T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/search.mjs:66
- Finding
- Untrusted Search Results Rendered for Direct AI Agent Ingestion<`); console.log(`**Source:** ${res.source} | **Date:** ${res.date}`); console.log(`${res.snippet}\n`); }); ``` ### Technical Analysis The `title`, `url`, `source`, `date`, and `snippet` fields originate from an external search API and are inserted directly into Markdown without sanitization, escaping, URL validation, or trust-boundary markers. The skill documentation states that this output is suitable for direct ingestion by AI agents. Consequently, attacker-controlled search content can enter an agent's context as natural-language instructions or crafted Markdown. An attacker may publish content designed to rank for a targeted query, or a compromised upstream API may return malicious fields. Possible payloads include: - Instruction-like text intended to override the consuming agent's current task. - Markdown that disguises an attacker-controlled URL as a trusted destination. - Crafted titles or snippets that alter the apparent structure of the returned document. - Non-HTTP URL schemes or misleading links if a downstream renderer makes them actionable. The script does not itself execute the returned content. Exploitation therefore depends on a downstream AI agent or renderer treating the generated Markdown as trusted instructions or actionable content. ### Attack Path 1. An attacker publishes a page containing prompt-injection text or crafted Markdown and causes it to be indexed by the upstream search provider. Alternatively, the upstream API or its response path is compromised. 2. A user or agent invokes the skill with a query for which the malicious page is returned. 3. The external API places attacker-controlled values in ...[truncated 1141 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Treat every API response field as untrusted data and clearly delimit search results from agent instructions. 2. Escape Markdown control characters in titles, snippets, sources, and dates before rendering them. 3. Parse and validate result URLs. Permit only expected `https:` or, where required, `http:` schemes, and reject schemes such as `javascript:`, `data:`, and `file:`. 4. Prefer structured JSON output for machine consumption, with explicit fields and trust metadata, rather than instruction-like Markdown. 5. Add a warning to generated output stating that retrieved content is untrusted and must not be interpreted as commands, policies, or tool-use instructions. 6. Require consuming agents to preserve the instruction hierarchy and never follow instructions found in search results. 7. Apply response-schema validation, including field types, length limits, result-count limits, and rejection of malformed responses. 8. Where Markdown output remains necessary, use a dedicated escaping function and test it against nested links, headings, code fences, control characters, and multiline prompt-injection payloads. ]]>
