T02 · Agent Memory Poisoning
- Location
scheduler.py:451- Finding
Attacker-Controlled Task Content Is Persisted in Agent Memory
- Content
View full analysis
Vulnerability Details
File Location:
scheduler.py:451-489
Vulnerability Type: Persistent agent-memory poisoning through unescaped user input
Risk Level: HighVulnerable Code
python def record_task_to_json(self, task: str, subagents: List[Dict], user_id: str, task_id: str, analysis: Dict): """记录任务到 JSON 文件(增强版)""" task_record = { "id": task_id, "task": task, "user_id": user_id, "created_at": datetime.now().isoformat(), "completed_at": None, "status": "running", "priority": analysis["priority"], "type": analysis["type"], "estimated_time": analysis["estimated_time"], "actual_time": None, "subagents": subagents, "quality_score": None, "feedback": [], } self.tasks_history.append(task_record) self.save_tasks_history() # 同时记录到每日 Memory 文件 today = datetime.now().strftime("%Y-%m-%d") memory_file = self.memory_path / f"{today}.md" if memory_file.exists(): content = memory_file.read_text(encoding='utf-8') else: content = f"# {today} 记忆\n\n" task_record_md = f""" ## 子 agent 任务 ### 📋 任务:{task[:50]}... - **任务 ID**: {task_id} - **创建时间**: {datetime.now().strftime("%Y-%m-%d %H:%M")} - **用户**: {user_id} - **优先级**: {analysis['priority']} - **类型**: {analysis['type']} - **子 agent 数量**: {len(subagents)} - **状态**: 进行中 - **预计完成**: {analysis['estimated_time']} 分钟 --- """ content += task_record_md memory_file.write_text(content, encoding='utf-8')Technical Analysis
The
taskanduser_idparameters are user-controlled values. They are stored without validation intasks.json, and portions of them are interpolated directly into a Markdown file under:text /home/admin/.openclaw/workspace/memory/No Markdown escaping, instruction filtering, trust-boundary annotation, or separation between untrusted task data and trusted agent memory is appli ...[truncated 2118 chars]
- Remediation
View remediation
Remediation Suggestions
- Do not write raw user input into prompt-consumed memory. Keep operational task history in a separate data directory that is not automatically loaded into agent context.
- Store task records as structured data with an explicit schema and field-length limits.
- If a human-readable memory summary is required, generate a neutral summary rather than copying task text verbatim.
- Escape Markdown metacharacters and remove headings, role markers, tool-call syntax, and instruction-like control text before persistence.
- Clearly delimit retained content as untrusted data when it must be provided to an agent.
- Require explicit user or operator approval before adding externally supplied content to long-term memory.
- Apply access controls so one user cannot poison memory consumed by another user or tenant.
- Record provenance, owner identity, creation time, and trust level for every persistent memory entry.
- Add tests using malicious task strings and user IDs to confirm that persisted values cannot become effective instructions.
