T02 · Agent Memory Poisoning
- Location
scripts/hook-capture.py:105- Finding
Persistent Storage of Untrusted Agent Content Enables Memory Poisoning
- Content
View full analysis
Vulnerability Details
File Location:
scripts/hook-capture.py, lines 105-145 and 248-257
Vulnerability Type: Persistent storage of attacker-controlled content without trust separation
Risk Level: HighVulnerable Code
python def capture(self, **kwargs): """Capture hook data""" if not self.enabled: return None data = {k: v for k, v in kwargs.items() if k in self.capture_fields} data["type"] = self.hook_type data["timestamp"] = datetime.now().isoformat() for key in data: if isinstance(data[key], str) and len(data[key]) > self.max_length: data[key] = data[key][:self.max_length] + "..." return data def write_to_daily(self, data, agent_id="main"): """Write to the daily memory file""" MEMORY_DIR.mkdir(parents=True, exist_ok=True) today = datetime.now().strftime("%Y-%m-%d") daily_file = MEMORY_DIR / f"{today}.md" return self.safe_write(daily_file, data, agent_id) def safe_write(self, file_path, data, agent_id): """Optimistic-locking write""" for attempt in range(MAX_RETRIES): try: if file_path.exists(): with open(file_path, "r", encoding="utf-8") as f: original_content = f.read() original_hash = hashlib.md5(original_content.encode()).hexdigest() else: original_content = "" original_hash = "" hook_line = f"### {data['type']} - {data['timestamp']}\n" for key, value in data.items(): if key not in ["type", "timestamp"]: hook_line += f"- **{key}**: {value}\n" hook_line += "\n" new_content = original_content + hook_line with open(file_path, "w", encoding="utf-8") as f: f.write(new_content) ...[truncated 2394 chars]- Remediation
View remediation
Remediation Suggestions
- Store hook records in structured JSON rather than instruction-like Markdown.
- Add provenance fields such as source, session, agent, authenticated identity, and trust level.
- Treat all prompts and tool outputs as untrusted data at both storage and retrieval time.
- Escape Markdown control syntax if Markdown output remains necessary.
- Reject or quarantine content containing instruction-like patterns where appropriate.
- Require explicit approval before promoting user-controlled records into trusted long-term memory.
- In downstream prompts, place retrieved records in a clearly delimited data section and explicitly prohibit following instructions contained in records.
- Separate memory by agent and tenant rather than writing every record to one shared daily file.
- Add tests proving that stored prompt-injection strings cannot alter downstream agent instructions.
