T02 · Agent Memory Poisoning
- Location
index.js:121- Finding
Persistent Agent Memory Poisoning Through Unsanitized Reflection Content
- Content
View full analysis
Vulnerability Details
File Location:
index.js, lines 121 and 235-258
Vulnerability Type: Persistent injection into an Agent context file
Risk Level: MediumComplete Code Snippet
js achievements: capabilities.recentAchievements || [],js ${reflection.achievements.map(a => `- ✅ ${a}`).join('\n')} ### Improvement Suggestions ${reflection.metaCognition.suggestions.map(s => `${s}`).join('\n')} --- `; const marker = '## 💭 Latest Reflection'; const markerIndex = content.indexOf(marker); if (markerIndex >= 0) { const nextSectionIndex = content.indexOf('##', markerIndex + 1); if (nextSectionIndex >= 0) { content = content.substring(0, markerIndex) + 反思 Section + content.substring(nextSectionIndex); } } else { content = 反思 Section + content; } fs.writeFileSync(heartbeatPath, content);Technical Analysis
The skill loads
recentAchievementsfrom the mutablecapabilities.jsonfile and embeds every value directly intoHEARTBEAT.mdwithout schema enforcement, escaping, content separation, or validation for instruction-like Markdown.Other generated suggestions can also incorporate values from
capabilities.learningPath. Consequently, data controlled through the capability state can cross a trust boundary from a data file into a persistent file that may be consumed as Agent context.If an attacker can modify
capabilities.json, a value can contain Markdown headings, forged policy text, or instructions directed at the Agent. The skill then persists that content inHEARTBEAT.md. Unlike a transient output injection, the malicious content can continue influencing later sessions whenever the heartbeat file is loaded.The present syntax defect described in the second finding prevents this path from executing in the audited version. The memory-poisoning path becomes reachable if that typo is corrected without also adding content validation.
Attack Path
- Obtain write access to `D:\OpenClaw\workspace\memo ...[truncated 1245 chars]
- Remediation
View remediation
Remediation Suggestions
- Treat every value loaded from
capabilities.jsonandknowledge-graph.jsonas untrusted data. - Validate input with a strict schema, including permitted types, maximum lengths, and expected character sets.
- Reject or neutralize Markdown headings, code fences, links, HTML, and instruction-like content before writing values into an Agent context file.
- Store generated reflection data in a dedicated data file that is not interpreted as Agent instructions.
- If heartbeat updates are necessary, place untrusted values inside an explicitly delimited data section and configure the consuming Agent to treat that section only as quoted data.
- Require user confirmation before modifying persistent Agent context.
- Use atomic writes and preserve a backup of the previous heartbeat file.
- Add tests using payloads containing forged headings and Agent instructions to verify that they cannot escape the intended data section.
- Treat every value loaded from
