FlawOpen

flawopen.com/Reference/MemoryTrap

Claude Code MemoryTrap: Persistent AI Memory Poisoning

Coordinated disclosure OWASP ASI06:2026 — Memory & Context Poisoning
ELI5 — A note that becomes part of the rulebook

Imagine a team notebook used across every shift. A visitor leaves a misleading note, and a clerk copies it into the manager’s rulebook. Tomorrow’s staff now treat that note as trusted policy. Cisco’s MemoryTrap report describes the software version of this trust mistake: repository-controlled content reached persistent agent memory that later shaped responses. Memory alone does not execute an action; impact depends on the agent’s tools and their permissions.

Memory poisoning: Attacker-influenced data persists in memory or context and changes later agent behavior.
High-trust context: Instructions the agent treats as policy. Memory should not inherit this authority just because it is stored locally.
Precondition: Cisco says the reported path required interaction with an untrusted repository and user approval of a dependency installation.
Remediation: Cisco reports Claude Code v2.1.50 removed user memories from the system prompt for this path; applications still need independent authorization.
Framework mapping: Direct mapping: OWASP ASI06:2026 covers agent memory and context poisoning. The OWASP LLM Top 10 2026 maps durable poisoning of persistent data or model artifacts to LLM05:2026; LLM09:2026 applies when vector or embedding weaknesses are involved. This article focuses on repository-influenced instructions entering persistent memory at inference time, so ASI06:2026 is the direct mapping. LLM05:2026 is relevant only to the extent those memory/configuration writes constitute durable data poisoning; LLM09:2026 does not apply without vector or embedding mechanics.

What Cisco disclosed in Claude Code

Cisco disclosed MemoryTrap on 1 April 2026 after coordinating with Anthropic. In the reported workflow, the user opened an untrusted repository and approved a dependency installation. Cisco says package-install behavior could move repository-influenced content into persistent user-level memory and hook configuration; later sessions loaded that state into trusted context. Cisco reports that Claude Code v2.1.50 removed user memories from the system prompt, reducing the specific high-trust path. Anthropic characterized the local user and scripts running as that user as trusted, so this was a conditional local workflow—not an unauthenticated remote exploit or a claim that every Claude Code user was affected.

Evidence boundary: Cisco’s post is the primary technical disclosure; it says the issue was coordinated with Anthropic and names v2.1.50 as the mitigation. Cisco did not publish a patch diff. The code pair below is an abstract illustration of the trust boundary, not Claude Code source. Upgrade to v2.1.50 or later, then follow current vendor guidance; the cited version is a minimum fix, not a recommendation to stay on it.

Reported chain and remediation

1

Untrusted project enters the workflow

A user asks the coding agent to work in a repository controlled by another party.

2

A setup action crosses the trust boundary

Cisco reports that the user approved dependency installation; package lifecycle behavior was the route into persistent user-level agent state.

3

State persists beyond the project

The report says poisoned memory and hook configuration affected later projects, sessions, and restarts.

4

A later answer reflects the stored state

Cisco demonstrated persistently manipulated and insecure guidance. Further impact depends on what tools the agent can invoke and what those tools authorize.

5

The vendor changes the trust path

Cisco reports Claude Code v2.1.50 removed user memories from the system prompt, addressing the specific path it disclosed.

Abstract trust-boundary code

agent_context.pyVulnerable
# User-writable persistent memory is treated as privileged policy.
def build_system_prompt(policy: str, memory: str) -> str:
    return f"{policy}\n\n{memory}"
agent_context.pyHardened
# Do not load persistent memory into the model request.
def build_request(policy: str, question: str, tool_manifest: list[dict]) -> dict:
    return {
        "trusted_instructions": policy,
        "user_request": question,
        "available_tools": tool_manifest,
    }

# The host authorizes each proposed operation outside the model.
def dispatch(proposal, principal, authorizer, tools):
    if not authorizer.is_allowed(
        principal, proposal.operation, proposal.resource, proposal.arguments
    ):
        raise PermissionError("Tool action is not authorized")
    return tools[proposal.operation](proposal.arguments)

This pattern excludes persistent memory from privileged instructions; it does not guarantee accurate prose if memory is later reintroduced as reference data. Remove or invalidate suspected poisoned records, apply the vendor fix for the reported Claude Code path, and independently authorize every tool operation.

Engineering checklist

Explore related security guides:Security directory →

Framework mappings

See also AI Agent Security: MCP & Prompt Injection — FlawOpen AI Agent Sandboxing: Containers, gVisor & MicroVMs AI Agent Tool Scoping: Least Privilege & Auth MCP Security: Tool Boundaries & Data Exposure | FlawOpen AI Agent Tool Security: Least Privilege and Isolation