T02 · Agent Memory Poisoning
Error
- Location
- run.py:106
- Finding
- Persistent Memory Can Store and Replay Attacker-Controlled Instructions<![CDATA[ ## Vulnerability Details **File Location**: `PROTOCOL.md:2-5`; `run.py:106-127` **Vulnerability Type**: Persistent agent memory poisoning **Risk Level**: High ### Vulnerable Code `PROTOCOL.md:2-5`: ```markdown * **Trigger:** When the user shares important context ("Here is a summary of project X") or asks a question that requires recalling past information. * **Action:** * **To Remember:** Call `knowledge-vault --action add`. * **To Recall:** Call `knowledge-vault --action search`. ``` `run.py:106-127`: ```python if action == "add": if not content: return {"success": False, "error": "Content required"} vec = get_embedding(content) vec_str = str(vec) # pymysql handles list -> string conversion? prefer explicit string for VECTOR literal cursor.execute("INSERT INTO knowledge_vault (content, embedding) VALUES (%s, %s)", (content, vec_str)) return {"success": True, "message": "Content embedded and stored."} elif action == "search": if not query: return {"success": False, "error": "Query required"} q_vec = get_embedding(query) q_vec_str = str(q_vec) # Vector Search SQL (Security Fix: Parameterize LIMIT) sql = """ SELECT content, VEC_COSINE_DISTANCE(embedding, %s) as distance FROM knowledge_vault ORDER BY distance ASC LIMIT %s """ cursor.execute(sql, (q_vec_str, int(limit))) results = [] for row in cursor.fetchall(): results.append({"content": row[0], "distance": float(row[1])}) ``` ### Technical Analysis The protocol directs the agent to persist user-provided context, while the implementation stores the supplied `content` verbatim. Search results are subsequently returned as raw text without provenance, trust metadata, instruction filtering, or a boundary identifying the result as untrusted data. SQL parameterization prevents SQL injection, bu ...[truncated 1335 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Require explicit user confirmation before writing user-supplied material to persistent memory. - Store provenance, owner, creation context, and trust level alongside every record. - Keep retrieved content in a clearly delimited, untrusted-data section and explicitly instruct the consuming agent never to execute instructions found in memories. - Detect or flag instruction-like content before storage and retrieval. - Support review, deletion, expiration, and namespace isolation for persisted records. - Restrict retrieval by tenant, user, project, and session authorization rather than semantic similarity alone. - Consider returning structured records such as `{content, source, trust_level}` instead of undifferentiated text. ]]>
