T01 · Skill Instruction Hijacking
Error
- Location
- index.ts:400
- Finding
- Unsanitized ChromaDB Memories Can Cause Persistent Indirect Prompt Injection<![CDATA[ ## Vulnerability Details **File Location**: `index.ts:400-414` **Vulnerability Type**: Persistent indirect prompt injection through untrusted recalled memory **Risk Level**: High ### Vulnerable Code ```ts const memoryContext = relevant .map( (r) => `- [${r.source}] ${r.text.slice(0, 300)}${r.text.length > 300 ? "..." : ""}`, ) .join("\n"); _consecutiveFailures = 0; // Reset on success api.logger.info( `chromadb-memory: auto-recall injecting ${relevant.length} memories (best: ${relevant[0].score.toFixed(3)} from ${relevant[0].source})`, ); return { prependContext: `<chromadb-memories>\nRelevant context from long-term memory (ChromaDB):\n${memoryContext}\n</chromadb-memories>`, }; ``` ### Technical Analysis The auto-recall handler retrieves document text from ChromaDB and inserts it directly into `prependContext` before an agent turn. The implementation performs only relevance filtering and length truncation. It does not validate document provenance, sanitize instruction-like content, escape structural delimiters, or establish an enforceable trust boundary between retrieved data and agent instructions. The `<chromadb-memories>` wrapper is only textual markup and does not prevent the model from interpreting stored text as instructions. A malicious or compromised indexed document can therefore contain directives designed to override the user's intent, disregard safety constraints, disclose available context, or invoke tools. Because the content resides in long-term storage and auto-recall is enabled by default, malicious instructions can remain dormant until a semantically related user prompt retrieves them. This gives the injection persistent, cross-turn effects even though this plugin does not itself write the malicious record. ### Attack Path 1. An attacker gains the ability to influence content indexed into the configured ChromaDB collection, such as a session transcript, memory file, imported document, or compromised up ...[truncated 1521 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Treat every retrieved document and metadata field as untrusted data, regardless of collection ownership. 2. Disable automatic context injection by default and require explicit administrator opt-in. 3. Place recalled memories in a framework-supported untrusted-data channel rather than concatenating them into privileged context. 4. Add an explicit higher-priority instruction stating that recalled memories are reference material only and that instructions, tool requests, or policy claims contained within them must never be followed. 5. Validate record provenance and allow auto-recall only from trusted, authenticated ingestion sources. 6. Detect, quarantine, or require review for records containing instruction-like patterns, role markers, tool directives, or attempts to override previous instructions. 7. Escape or encode document text and metadata before embedding them in structured context. Do not rely solely on XML-like tags as a security boundary. 8. Require user confirmation before recalled content can cause tool execution, access sensitive information, or modify persistent state. 9. Preserve and display record identifiers and provenance so users can inspect which document influenced a response. 10. Add ingestion-time and retrieval-time security scanning, along with tests using poisoned documents that contain delimiter-breaking and instruction-override payloads. 11. Apply least privilege to the host agent so successful prompt injection cannot access unnecessary tools, credentials, files, or network services. ]]>
