T02 · Agent Memory Poisoning
Error
- Location
- src/index.ts:171
- Finding
- Persistent Agent Memory Poisoning Through Untrusted Standing Instructions<![CDATA[ ## Vulnerability Details **File Location**: `src/index.ts:171-184` **Vulnerability Type**: Persistent prompt injection through stored memory **Risk Level**: High ### Vulnerable Code ```ts if (cfg.autoInjectInstructions === true) { api.on('before_agent_start', async (event: { prompt?: string }) => { const instructions = store.getByCategory('instruction', 10); if (instructions.length === 0) { return undefined; } const instructionList = instructions .map((m: { content: string }) => `- ${m.content}`) .join('\n'); api.logger.info?.(`memory-tools: injecting ${instructions.length} standing instructions`); return { prependContext: `<standing-instructions>\nRemember these user instructions:\n${instructionList}\n</standing-instructions>`, }; }); } ``` ### Technical Analysis When `autoInjectInstructions` is enabled, the plugin retrieves persisted memories in the `instruction` category and inserts their content verbatim into the context supplied before agent startup. The stored content is not escaped, constrained to a safe instruction grammar, labeled with its provenance, or treated as untrusted data. An attacker-controlled memory can therefore contain directives such as instructions to ignore later requests, misuse tools, disclose data, or close the pseudo-XML delimiter and introduce new context sections. Because the content is persisted to disk, the malicious instruction can continue to influence future conversations rather than only the session in which it was stored. This is best classified as agent memory poisoning rather than direct modification of the Skill's static instruction text. The affected feature is documented and disabled by default, which reduces default exposure but does not address the unsafe trust transition when it is enabled. ### Attack Path 1. The administrator enables `autoInjectInstructions`. 2. An attacker causes attacker-controlled text to be passed to `memory_store` ...[truncated 1074 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Do not automatically promote free-form memory content into agent instructions. 2. Require explicit, authenticated user approval before a memory can enter the `instruction` category or become eligible for automatic injection. 3. Record and enforce provenance, including the originating user, channel, message, and approval status. 4. Represent standing instructions using a constrained structured schema rather than arbitrary natural-language content. 5. Escape or reject structural delimiters and markup that can terminate or alter the surrounding context block. 6. Inject stored entries as clearly labeled untrusted reference data, not as authoritative system-level instructions. 7. Apply strict size, character, and content limits. 8. Provide users with an auditable list of active standing instructions and a way to revoke them. 9. Add tests covering closing tags, instruction-confusion payloads, cross-session persistence, and memories derived from untrusted external content. ]]>
