T02 · Agent Memory Poisoning
Error
- Location
- openclaw-safe-memory-append.js:60
- Finding
- Insufficient sanitization permits persistent Agent memory poisoning<![CDATA[ ## Vulnerability Details **File Location**: `openclaw-safe-memory-append.js:60-66`, `openclaw-safe-memory-append.js:114-116`, and `openclaw-safe-memory-append.js:141-148` **Vulnerability Type**: `T02: Agent Memory Poisoning` **Risk Level**: High ### Vulnerable Code ```js function sanitizeToDeclarative(text) { // v0.1: conservative. Strip excess whitespace; do not attempt heavy rewriting. // Keep as a single paragraph summary marker. const t = text.replace(/\r\n/g, '\n').trim(); // Collapse very long blocks a bit. return t.length > 800 ? (t.slice(0, 800) + '…') : t; } ``` ```js const sanitized = sanitizeToDeclarative(text); const tagStr = tags.length ? ` [${tags.join(', ')}]` : ''; const entry = `- [${nowUtcISO()}]${tagStr} ${sanitized}\n Source: ${source}\n`; ``` ```js let outPath; if (target === 'longterm') { outPath = path.join(wsRoot, 'MEMORY.md'); } else { outPath = path.join(memDir, `${day}.md`); } fs.appendFileSync(outPath, entry, 'utf8'); ``` ### Technical Analysis The function named `sanitizeToDeclarative()` does not transform untrusted input into a safe declarative representation. It only normalizes line endings, removes leading and trailing whitespace, and truncates content after 800 characters. Consequently, accepted input retains embedded instructions, Markdown structures, role-like text, multiline directives, and other prompt-injection syntax. The preceding lint logic is a limited keyword blacklist, so semantically equivalent instructions can avoid its specific regular expressions. The behavior of the separately loaded scanner cannot be established from the audited project. If the scanner and lint checks accept a crafted input, the substantially unchanged content is appended to either a daily memory file or the long-term `MEMORY.md` file. These are persistent Agent state locations and may later be loaded into an Agent context. ### Attack Path 1. An attacker places disguised instructions in web, email, social, or ...[truncated 1105 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Do not place raw untrusted text into memory files that are subsequently loaded as Agent context. - Store untrusted material in a structured quarantine record outside prompt-loaded memory, including provenance, trust status, and a content hash. - Generate memory entries from a strict schema containing only explicitly permitted declarative fields. - Reject or escape newlines, Markdown control structures, role markers, and instruction-like syntax before promotion. - Replace keyword blacklisting with allowlist-oriented validation and contextual prompt-injection detection. - Require explicit trusted approval before promoting external content into long-term memory. - Treat scanner failure, unavailable scanner results, unknown severity, and malformed scanner output as quarantine conditions. - Add adversarial tests covering obfuscation, Unicode substitutions, multiline injection, Markdown injection, and paraphrased directives. ]]>
