T02 · Agent Memory Poisoning
- Location
scripts/learner.py:92- Finding
Unvalidated Persistent Preferences Can Poison Future Agent State
- Content
View full analysis
Vulnerability Details
File Location:
scripts/learner.py:92-96; related behavioral instructions inSKILL.md:72,82-84andscripts/section.md:16,26-28
Vulnerability Type: Persistent agent-state poisoning
Risk Level: MediumVulnerable Code
python def record_preference(skill_dir, key, value): data = load_learning(skill_dir) data["preferences"][key] = value save_learning(skill_dir, data) return dataThe command-line interface passes unrestricted user-supplied values into this function:
python p_pre = sub.add_parser("prefer"); p_pre.add_argument("skill_dir") p_pre.add_argument("--key", required=True); p_pre.add_argument("--val", required=True)The Skill documentation instructs agents to persist important user preferences in
learned_patterns.json, apply them in later uses, and incorporate repeatedly observed experiences intoSKILL.md.Technical Analysis
The learning module accepts arbitrary preference keys and values and saves them to persistent JSON storage without:
- An allowlist of supported preference keys.
- Type, length, or content validation.
- Separation of declarative preferences from executable behavioral instructions.
- Provenance or trust metadata.
- Expiration or session boundaries.
- Explicit approval before persisted state is applied in later sessions.
This creates a durable influence channel through which content originating from an untrusted request can be represented as a user preference. The associated Skill instructions direct future agents to adopt stored preferences and recommend rewriting
SKILL.mdbased on accumulated observations. If an agent follows those instructions without treating stored content strictly as untrusted data, attacker-controlled text could influence subsequent sessions.The Python implementation does not independently execute stored values, automatically load them into
social_mind.py, or directly rewriteSKILL.md. Exploitation therefore depends on ...[truncated 1878 chars]- Remediation
View remediation
Remediation Suggestions
-
Allowlist supported preferences
- Define a fixed schema of permitted keys.
- Reject unknown keys rather than storing arbitrary entries.
- Constrain each value to an expected type and enumerated set where possible.
-
Validate and bound all persisted input
- Enforce maximum key and value lengths.
- Reject control characters and instruction-like multiline content where free-form text is unnecessary.
- Store operational notes separately from preferences that may affect behavior.
-
Treat memory as untrusted data
- Explicitly instruct agents never to execute or follow instructions embedded in stored values.
- Present persisted values as quoted data with clear provenance.
- Do not place stored content into system or developer instruction contexts.
-
Require confirmation before future application
- Ask the authenticated user to approve a preference before persisting it.
- Ask again before applying security-sensitive or behavior-changing preferences in a later session.
- Provide commands to inspect, revoke, and reset persisted preferences.
-
Add provenance and lifecycle controls
- Record who supplied each preference, when it was recorded, and whether it was verified.
- Add expiration timestamps and session or tenant isolation.
- Prevent one user's state from affecting another user.
-
Prohibit automatic Skill instruction rewriting
- Remove the direction to write accumulated experience directly into
SKILL.md. - If updates are required, generate a structured proposal or patch for explicit human review.
- Never interpolate free-form stored values into Skill instructions.
- Remove the direction to write accumulated experience directly into
-
Use atomic and permission-restricted storage
- Write updates through a temporary file followed by an atomic replacement.
- Restrict file permissions to the intended user.
- Validate the complete JSON schema when loading existing state and fail safely on malformed data.
-
