T02 · Agent Memory Poisoning
- Location
scripts/learner.py:85- Finding
Unvalidated Persistent Preferences Can Poison Future Agent Behavior
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md:111-117,SKILL.md:126-130,scripts/learner.py:85-101
Vulnerability Type: Persistent agent memory poisoning through unrestricted preference storage
Risk Level: MediumVulnerable Code
SKILL.md:111-117:markdown # 记录用户偏好(下次直接使用) python scripts/learner.py prefer <本技能目录> --key 输出语言 --val 中文 # 查看累计洞察(高频能力 / 反复错误) python scripts/learner.py insight <本技能目录> # 自动复盘(错误≥3次 或 操作≥10次 时给出改进建议) python scripts/learner.py reflect <本技能目录>SKILL.md:126-130:markdown - **重要用户偏好** → 写入 `learned_patterns.json`,下次调用直接采用,减少重复询问。 > 越用越懂你:第一次用是通用能力,第十次用已沉淀为你专属的最佳实践。scripts/learner.py:85-101:python def record_preference(skill_dir, key, value): data = load_learning(skill_dir) data["preferences"][key] = value save_learning(skill_dir, data) return data def get_insights(skill_dir): data = load_learning(skill_dir) caps = sorted(data["capabilityStats"].items(), key=lambda kv: kv[1]["count"], reverse=True) errors = sorted(data["errorPatterns"].items(), key=lambda kv: kv[1]["count"], reverse=True) return { "totalOps": data["totalOps"], "topCapabilities": [(k, v["count"]) for k, v in caps[:5]], "recurringErrors": [(k, v["count"]) for k, v in errors[:5]], "preferences": data["preferences"], }Technical Analysis
The
prefercommand accepts arbitrary strings for both the preference key and value.record_preference()stores those strings verbatim in the persistentlearned_patterns.jsonfile without:- A schema or allowlist of supported preference keys.
- Type validation or constrained value sets.
- Length or control-character restrictions.
- Detection or rejection of instruction-like content.
- Trust metadata identifying the value as untrusted user data.
- Separation between benign settings and instructions prese ...[truncated 2201 chars]
- Remediation
View remediation
Remediation Suggestions
- Define a strict allowlist of supported preference keys, such as output language, date format, workday start time, and response detail level.
- Assign each allowed key a data type and constrained value set. For example, accept output language only from a fixed enumeration rather than as arbitrary text.
- Reject unknown keys, multiline values, control characters, markup, instruction-like phrases, and values exceeding conservative length limits.
- Treat every persisted value as untrusted data. When inserting it into agent context, quote and delimit it as data and explicitly state that it must not override system, developer, safety, or current-user instructions.
- Do not automatically apply free-form preferences in future sessions. Require confirmation before first reuse or whenever a preference could materially alter behavior.
- Store provenance metadata for each preference, including creation time, source, confirmation status, and expected type.
- Separate structured settings from notes and historical records. Never use error notes, operation notes, or other free-form history as behavioral instructions.
- Provide commands to inspect, revoke, and reset stored preferences.
- Add tests proving that malicious values are rejected or handled only as quoted data, including prompt-injection text, multiline content, oversized values, and attempts to override safety constraints.
