T02 · Agent Memory Poisoning
- Location
- SKILL.md:64
- Finding
- Untrusted Research Content Can Be Persisted into Agent Memory and Skills<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:64-76`; related untrusted content source in `scripts/scan_sources.py:25-59` **Vulnerability Type**: `T02: Agent Memory Poisoning` **Risk Level**: Medium ### Complete Code Snippets `SKILL.md:64-76`: ```markdown ### Step 4: RESEARCH Actively explore the missing concept. - Search docs, existing skills, external sources - Use web_search, browser, terminal, session_search - Validate the discovery's relevance ### Step 5: INTEGRATION Update knowledge/skills. - **If an existing skill is incomplete**: `skill_manage(action='patch')` with new info - **If a new pattern is discovered**: `skill_manage(action='create')` for a new skill - **If a stable fact is learned**: `memory(action='add')` for durable facts - **If a tool/command is discovered**: document in the appropriate skill ``` Related external-content retrieval in `scripts/scan_sources.py:25-59`: ```python def scan_youtube_channel(channel_id, last_scanned): """Scan a YouTube channel for new videos since last_scanned.""" import urllib.request import xml.etree.ElementTree as ET url = f"https://www.youtube.com/feeds/videos.xml?channel_id={channel_id}" headers = {"User-Agent": "Mozilla/5.0"} req = urllib.request.Request(url, headers=headers) try: html = urllib.request.urlopen(req).read().decode("utf-8") root = ET.fromstring(html) ns = {"atom": "http://www.w3.org/2005/Atom"} entries = root.findall("atom:entry", ns) new_videos = [] for entry in entries: published = entry.find("atom:published", ns).text vid = entry.find("atom:id", ns).text.replace("yt:video:", "") title = entry.find("atom:title", ns).text pub_date = datetime.fromisoformat( published.replace("Z", "+00:00") ).date() scan_date = datetime.fromisoformat(last_scanned).date() if pub_date > scan_date: n ...[truncated 2970 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Treat all web pages, feed fields, titles, descriptions, and search results as untrusted data rather than agent instructions. 2. Add an explicit rule forbidding the agent from following tool-use, memory-write, skill-update, or safety-override instructions found in researched content. 3. Require explicit user confirmation before any `memory(action='add')`, `skill_manage(action='patch')`, or `skill_manage(action='create')` operation derived from external material. 4. Separate research and integration into distinct stages. Store candidate findings in a non-executable review queue before promoting them into persistent state. 5. Record provenance for every persisted fact, including source URL, retrieval date, quoted evidence, confidence, and whether independent corroboration was performed. 6. Require corroboration from multiple trusted sources before persisting operational commands, security guidance, or behavioral rules. 7. Apply a strict schema to persistent entries and reject imperative content, tool-call syntax, embedded prompts, encoded instructions, and requests to override existing constraints. 8. Restrict automated skill updates to documentation-only changes where possible. Require manual review for changes that introduce commands, tool calls, network access, or file writes. 9. Configure an allowlist of trusted source domains and validate parsed channel identifiers before making requests. 10. Preserve an audit log and rollback mechanism for all memory and skill modifications so poisoned state can be identified and reverted. ]]>
