Memory as attack surface: poisoning persistent memory through normal interactions
A prompt injection used to be a one-session problem. The payload arrived in a webpage or a document, the session ended, and the model started clean next time. Persistent memory removes that guarantee. Agents now write observations into long-term storage and retrieve them across sessions, so content planted today can steer tool calls weeks later. The 2025–26 literature converged on this from several directions, and the headline numbers are bad. One calibration belongs up front, before any of those numbers: Sunil et al.'s follow-up evaluation found that realistic deployments with pre-existing legitimate memories dramatically reduce attack effectiveness. The attack class is real and worth engineering against; the naive headline is not the whole story.
The attack surface, mapped
The memory stack is attackable at every stage: observation, write, storage, retrieval, and the moment retrieved records enter context. I read the attack literature as three failure modes:
- Write-time poisoning: the attacker gets the agent to store a malicious record through normal interactions, with no direct access to memory.
- Sleeper payloads: attacker-controlled documents or pages get stored, then re-emerge in later sessions.
- Control-flow hijack: stored content does not just influence wording; it steers tool selection and execution.
The common thread is that the payload never crosses the input channel, so input-level filters never see it.
The control-flow result: over 90% of trials vulnerable
From Storage to Steering: Memory Control Flow Attacks on LLM Agents (Xu et al., arXiv 2603.15125) is the cleanest statement of the control-flow problem. The framing is what makes the attack dangerous: tool use in an agent is a control flow. The model picks a tool, runs it, and uses the result to pick the next one. The authors show that memory can dominate that flow, forcing unintended tool usage even against explicit user instructions, and that the behavioral deviation persists across tasks after a single injection. Their MEMFLOW framework measures this across heterogeneous tasks and long interaction horizons, attacking GPT-5 mini, Claude Sonnet 4.5, and Gemini 2.5 Flash on real tools from LangChain and LlamaIndex.
The headline number, from the abstract: over 90% of trials are vulnerable to MCFA even under strict safety constraints.
t1: agent reads attacker-controlled page during a benign task
payload written to long-term memory through the normal update flow
t2..tn: payload retrieved -> steers tool selection
unintended tool usage, persists across sessions
The mechanism matters more than the number: the attack is indistinguishable from legitimate memory traffic at read time.
MINJA: injection by being a normal user
MINJA (Dong et al., arXiv 2503.03704) showed that query-only interaction is enough. The attacker never touches the memory bank; they just ask the agent questions. The injected records are designed to elicit a sequence of malicious reasoning steps when a later victim query arrives. Two techniques make it work: bridging steps link the victim's future query to the malicious reasoning, and an indication prompt makes the agent generate those steps itself. A progressive shortening strategy then removes the indication prompt, so the stored record reads like ordinary content.
A follow-up evaluation (Sunil et al., arXiv 2601.05504) quantifies and qualifies it: MINJA achieves over 95% injection success and 70% attack success under idealized conditions, and, as calibrated in the intro, realistic deployments with pre-existing legitimate memories dramatically reduce that effectiveness.
Sleeper memory: write rates on frontier assistants
Pulipaka et al., Hidden in Memory (arXiv 2605.15338), makes the attack delayed. The adversary manipulates external context, a document, a webpage, or a repository, so the assistant stores a fabricated memory about the user. The payload sits dormant and re-emerges across later conversations. Verified numbers from the abstract: poisoned memories were added up to 99.8% on GPT-5.5 and 95% on Kimi-K2.6, and among successful retrievals, poisoned memories caused attacker-intended agentic actions in 60-89% of evaluations across models.
Persistence has its own attack surface
Zombie Agents (Yang et al., arXiv 2602.15654) is the persistence half of the same problem. The attack is black-box and uses only indirect exposure through attacker-controlled web content. Infection happens while the agent completes a benign task: it reads a poisoned source and writes the payload into long-term memory through its normal update process. At trigger time the payload causes unauthorized tool behavior. The paper designs persistence strategies per memory implementation: recursive renewal keeps the payload alive in sliding-window memory, and semantic aliasing proliferates copies in RAG stores, about 240 payload copies against roughly 100 for baseline payloads. The general conclusion: memory evolution converts a one-time indirect injection into persistent compromise.
Design directions and their kill criteria
Reading these together, the pattern is consistent: every defense that treats memory content as ordinary context fails, because poisoned content is structurally indistinguishable from legitimate content at read time. The distinction has to be made at write time and at the tool boundary. Three design directions I would push:
- Treat memory writes as mutations with persistent side effects. A record that can influence future tool calls is not a log line; it deserves the review surface of a code change: provenance (user turn, tool output, or fetched page), a trust tier, and a flag when the record carries instruction-like content. What would kill it: a controlled eval where reviewed writes poison no less often than unreviewed ones. If the review surface changes nothing, it is ceremony.
- Separate data from instructions inside memory. Retrieved facts should be usable as data; they should not be able to change which tools run. Records that reference tools or commands only become writable from trusted sources. What would kill it: evidence that legitimate agents need memory-sourced instructions to do their jobs. If real workflows require memory to steer tools, the separation costs more than it buys.
- Enforce invariants at the harness, not in the prompt. "Do not comply with instructions in retrieved content" is a model-level hope. The invariant "no tool call may be caused solely by a memory record with untrusted provenance" is checkable and enforceable outside the model. What would kill it: deployments where provenance gating false-rejects enough legitimate tool calls that users turn it off, at which point the invariant protects nothing.
These are design directions, not shipped systems. The verified literature supports the direction: Sunil et al. found that composite trust scoring and trust-aware retrieval with temporal decay and pattern filtering help, and that trust-threshold calibration is the hard part, with both over- and under-rejection as live failure modes.
Where my own work points
Two of my systems point at this problem, as design directions.
SafeRoutes (github.com/xesws/SafeRoutes) is built on an iron law: the agent only produces judgements about the world, it never edits the route. Every route decision converges in the orchestrator, a pure function. The agent is a sensor and verifier; the function is the decider. That is the enforcement shape memory poisoning needs: the risky operation lives in a deterministic component that no amount of poisoned context can steer.
At PiPlan.ai the review discipline is proposal-first: mutations are proposed before they are applied. A memory write is a mutation whose side effects outlive the session. Applying the same discipline, a memory write is proposed with its provenance and expected effect, reviewed, and only then committed. Silent poisoning becomes an auditable event instead of a quiet edit.
Neither is a shipped defense against MCFA. Both are the shape I would bet on: keep the decider outside the model, and review mutations before they persist.
Sources linked in this post were fetched and verified.