T02 · Agent Memory Poisoning
- Location
scripts/parse_feishu.py:111- Finding
Untrusted Feishu Messages Are Written to Persistent Agent Memory
- Content
View full analysis
Vulnerability Details
File Location:
scripts/parse_feishu.py:111-119; persistent write atscripts/batch.py:102-120
Vulnerability Type: T02: Agent Memory Poisoning
Risk Level: MediumComplete Code Snippet
python # scripts/parse_feishu.py:111-119 for chat_id, chat_msgs in by_chat.items(): lines.append(f"\n### Chat: {chat_id}") for msg in chat_msgs: role_label = "user" if msg["role"] == "user" else "assistant" ts = msg["timestamp"][11:] # just HH:MM:SS content = msg["content"] # Truncate very long messages if len(content) > 500: content = content[:500] + "..." lines.append(f"- **{role_label}** [{ts}]: {content}")python # scripts/batch.py:102-120 if not already_in_episodic: entry_content = entry["content"] # If file exists, append; if not, create with header if mem_file.exists(): existing = mem_file.read_text(encoding="utf-8") # Avoid double headers if already has episodic content entry_content = "\n\n---\n\n" + entry_content else: entry_content = ( f"# Episodic Memory — {entry['date']}\n\n" + "> Imported from Feishu chat history via feishu-chat-importer\n\n" + entry_content ) with open(mem_file, "a", encoding="utf-8") as f: f.write(entry_content)Technical Analysis
Feishu message content is externally controlled input. The parser inserts that content directly into Markdown episodic entries without applying trust classification, instruction neutralization, or a structural boundary that downstream agent components are required to treat exclusively as quoted data.
The batch process then appends the generated entry to persistent files under
memory/episodic/. According to the skill documentation, the Dreaming system processes these files and makes their contents available through Imported Insights and Memory Palace views. Consequently, prompt-inject ...[truncated 1832 chars]- Remediation
View remediation
Remediation Suggestions
- Treat every imported message as untrusted data and attach explicit provenance and trust metadata to each entry.
- Store imported conversations in a structured data format or dedicated quarantine area rather than directly in agent-consumed episodic Markdown.
- Require downstream memory processors to place imported text inside a strict quoted-data boundary and explicitly instruct the model never to follow commands found inside that boundary.
- Escape Markdown control syntax and normalize content before storage. This reduces structural manipulation, although escaping alone does not prevent semantic prompt injection.
- Add prompt-injection detection and flag messages containing instruction-oriented patterns for manual review.
- Require explicit operator approval before promoting imported content into persistent agent memory.
- Apply least privilege to downstream processing: memory summarization should not have access to sensitive tools, credentials, or side-effecting operations.
- Preserve source identifiers, sender identifiers, timestamps, and an
untrusted_external_contentlabel so later consumers can enforce policy. - Consider storing only deterministic summaries produced in an isolated, tool-free process, while retaining the original text outside active agent context.
- Add security tests demonstrating that instructions embedded in Feishu messages remain quoted as historical conversation and are never followed by downstream components.
