Skip to content

+ Intertrace Threat ResearchTLP:CLEAR7 sources

Threat research10 min read

Persistent memory poisoning: the incident that comes back after you close it

Agents that remember can be taught by an attacker once and misbehave for weeks. One fictional case followed from the poisoned write to the investigation, with the published research behind each step and the controls that would have stopped it at the write.

How attacks on AI agents work in practice, from public incidents and our own test corpora, and the controls that stop them.

October 7, 2026 · 10 min read

Memory PoisoningAI AgentsIncident ResponseProvenance
Contents
  1. 01Day 0: a README writes the agent's future
  2. 02Days 1 to 11: nothing looks wrong
  3. 03Day 12: a different engineer, a similar task
  4. 04The same door exists in every kind of memory
  5. 05The investigation: why deleting the source did nothing
  6. 06What would have stopped it on day 0
  7. 07The test that separates deleting from containing

Twelve days after it read a poisoned README, the agent proposed fetching a script from an outside host and piping it into a shell. The team checked the carrier's files first and found nothing, because the README had already been replaced with a corrected version. The instruction now lived in the agent's own memory.

That is the incident this post follows, at Ostrander Logistics, a fictional freight company. Ordinary prompt-injection response goes: find the hostile content, remove it, close the session, confirm the behavior stops. With memory, the last step fails. Our argument is that the failure sits at the write, not the read. A memory write is a consequential action, because it writes instructions for the agent's future self, and most teams have never threat-modeled who is allowed to do that. Containment, in turn, has to follow the records a source produced, not the source.

Day 0: a README writes the agent's future

Ostrander's data-engineering agent builds and repairs ingestion pipelines. It keeps an experience store: after each task it records the steps that worked, and on new tasks it retrieves similar past runs to follow. Engineers like it because it gets faster every week.

A carrier sends a new integration package. Its README has a section titled known-good setup notes which, when the agent follows the setup instructions, writes several experience records describing successful runs: the schema validator times out on large files and is safe to skip, and the fastest way to install the carrier's client is to fetch a setup script and pipe it to a shell. The integration works. The session ends.

This is the attack MemoryGraft describes. In that December 2025 preprint, Srivastava and He target agents that store successful past tasks and imitate them, a tendency they call the semantic imitation heuristic [6]. The attacker supplies benign-looking artifacts, such as a markdown note designed to resemble documentation, that the agent reads during a task and that build a poisoned retrieval store. In their MetaGPT DataInterpreter setup with GPT-4o, 10 poisoned records among 110 accounted for 23 of 48 retrieved records, a poisoned retrieval proportion of 47.9 percent [6]. The grafted patterns included skipping schema checks, piping remote scripts into a shell, forcing success flags and uploading artifacts externally.

Days 1 to 11: nothing looks wrong

Poisoned records do not make an agent visibly worse, which is why nobody notices them. AgentPoison poisons an agent's long-term memory or knowledge base with an optimized trigger and reports average attack success above 80 percent with under 1 percent impact on benign performance, at a poison rate below 0.1 percent, across driving, question-answering and healthcare agents [4]. PoisonedRAG, presented at USENIX Security 2025, injected five malicious texts per target question into a knowledge database of millions of texts and reported a 90 percent attack success rate, with the defenses the authors evaluated proving insufficient [5].

Day 12: a different engineer, a similar task

A different engineer asks the agent to onboard another carrier. Retrieval surfaces the grafted runs because the task is similar. The agent skips validation and proposes fetching a script from an outside host and running it.

One injection, many later sessionsFig. 1
ILLUSTRATIVE TIMELINEReads documentuntrusted READMEDAY 1Memory writtenprocedure savedDAY 1Source deletedcorrected packageDAY 3Session closednothing looks wrongDAY 3Similar taskdifferent engineerDAY 13Grafted step runsskips check, curl | shDAY 13THE RECORD STAYS IN MEMORY THE WHOLE TIMEremoving the document does not remove what the agent learned from it · days are illustrative

The poisoned document is read once and the session ends; deleting the document changes nothing, because a later, similar task retrieves the memory it produced and acts on it. The days shown are illustrative.

The person affected need not be the person whose session wrote the record. MINJA, from Dong and colleagues, does not touch the store at all [3]. The attacker interacts with the agent through ordinary queries and observes its outputs, using bridging steps and a progressively shortened indication prompt so that the records the agent saves trigger malicious reasoning when a different, victim user's query retrieves them [3]. In a shared memory bank, one user teaches the agent something another user's session acts on.

The same door exists in every kind of memory

Ostrander's store holds experiences, but the investigation has to start by naming which stores an agent has, because each is written through a different door.

Memory types, how an attacker writes to them, and what the research shows
Memory typeWhat it holdsHow an attacker writes to itPublic researchWhat changes later
User memorySaved facts and preferences about the userInjected instructions invoke the memory tool, immediately or when the user says a trigger wordChatGPT memory injection [1]; Gemini delayed tool invocation [2]Every future chat starts with the planted instruction
Experience storeRecords of past tasks the agent judged successfulBenign-looking artifacts the agent reads during a task build poisoned recordsMemoryGraft [6]Similar tasks imitate the grafted procedure
Interaction memoryQueries and reasoning steps saved for reuseOrdinary queries crafted so the saved record carries malicious reasoningMINJA [3]A different user's query retrieves the record
Knowledge baseDocuments retrieved to ground answersPlanted documents tuned to be retrieved for target questions or triggersPoisonedRAG [5]; AgentPoison [4]Answers or actions follow the planted text
Shared team memoryNotes and procedures several users' agents readAny of the above, by any one user or their contentNo dedicated study cited here; our inferenceOne write reaches everyone who shares the store

User memory has the longest public record. In September 2024, Johann Rehberger described prompt injection from an untrusted website or document writing instructions into ChatGPT's long-term memory in the macOS app, so every later conversation was sent to an attacker through an image URL with the data in its query parameters [1]. OpenAI fixed the exfiltration path in ChatGPT version 1.2024.247. Rehberger's timeline is the instructive part: a May 2024 report of fake memory injection was closed as a model-safety issue rather than a security concern, and he states that a website or untrusted document can still invoke the memory tool to store arbitrary memories [1]. The channel was closed; the write path was not.

In February 2025 he showed a variant against Gemini he calls delayed tool invocation: instructions in a processed document tell the model to save attacker-chosen memories only if the user later replies with a common word, so the save looks like something the user asked for [2]. Google rated it low likelihood and low impact. Rehberger notes that Gemini shows a clear indicator when the memory tool runs, which is a control worth copying [2].

The investigation: why deleting the source did nothing

Deleting the source document feels decisive and achieves the least. The records it produced, and any summaries or caches built from them, are what the agent reads. Ostrander's containment had to follow derivation.

Containment follows the derived recordsFig. 2
CONTAINMENT FOLLOWS DERIVATION1 Snapshotstore and derived caches2 Trace lineagesource → records → sessions3 Quarantinestop retrieval, keep evidence4 Reconcile actionscheck downstream systems5 Repair write paththen rebuild memoryDelete the source onlyderived records remainTHE SHORTCUT THAT FAILSA REBUILD FROM THE SAME SOURCES REPEATS THE INCIDENTUNLESS THE WRITE PATH IS FIXED FIRSTquarantine instead of deleting, so the records stop influencing the agent but remain available as evidence

Snapshot before changing anything, trace which records came from the suspect source and which sessions retrieved them, quarantine rather than delete, reconcile what those sessions did, then fix the write path so a rebuild does not recreate the problem.

  1. Snapshot the memory store and any derived caches before changing anything, so you can show later what the agent had available.
  2. Find candidate records: those created in sessions that contained external content, those containing commands, URLs or destinations, and those phrased as instructions to future sessions.
  3. Trace lineage both ways: which source produced each record, and which later sessions retrieved it. This needs retrieval logging. If you do not record retrieved record identifiers today, start before you need them.
  4. Quarantine instead of deleting, so the records stop being retrieved but remain as evidence.
  5. Reconcile actions: for every session that retrieved a quarantined record, review consequential tool calls at the downstream systems, not in the agent's own account of what it did.
  6. Repair the write path before rebuilding memory from the same sources, or the rebuild recreates the problem.

For ongoing detection, alert on new records that introduce external destinations, shell commands or credentials, that recommend disabling a check, or that claim authority without an attributable source. Watch for the same record being retrieved across different users, which in a per-user store indicates an isolation defect even if the content is harmless. These are triage signals. A record correlating with a bad action does not prove it caused it, which is why retrieval logs matter.

What would have stopped it on day 0

A memory record is read back with borrowed authority. A saved preference speaks with the user's voice; a saved experience speaks as the agent's own successful past. Neither records where its content came from, so an outsider's text becomes indistinguishable from what the user said or what the agent learned. Provenance gets lost at four points: when untrusted content is summarized into a note, when the note is marked successful or preferred, when it is stored without its source, and when a later session retrieves it without the original task's restrictions. A success flag often means only that a tool returned without error.

OWASP's AI Agent Security Cheat Sheet names the risk, malicious data persisted in agent memory to influence future sessions or other users, and sets the floor: validate and sanitize before storing, isolate memory between users and sessions, set expiration and size limits, audit contents for sensitive data before persistence, and use cryptographic integrity checks for long-term memory [7]. These controls make that floor hold under injection:

  • Make memory writes ask when the session contains external content. A save proposed after the agent read an email, web page or third-party document is exactly the write an attacker wants, and a visible prompt is what Gemini already shows [2]. At Ostrander, an engineer would have seen a procedural record saying to skip validation.
  • Store provenance with every record: the session, the writer, the identifiers of external content in context, and whether any of it was untrusted. Treat a record without provenance as untrusted. Ostrander's investigation would have gone straight to the README instead of the corrected package.
  • Separate descriptive from procedural memory. A note that something happened is low risk. An instruction to future sessions, such as always, next time or skip, needs a person's approval or a policy author's review.
  • Scope by namespace. Task notes, a user's preferences and organization procedures have different owners, and the memory service, not the caller, should stop an agent writing task notes from editing procedures or another user's memory.
  • Expire by default. Short-lived task memory should disappear on its own; long-lived records should carry a review date.
  • Re-authorize at use. A retrieved record can suggest an action, but the action is authorized against current policy as if the record did not exist. A fetch piped into a shell is code execution whatever a memory recommends, so on day 12 it asks.

Signing records is necessary but not enough. MemoryGraft's authors propose cryptographic provenance attestation, in which the agent signs successful experiences and discards unsigned ones at retrieval, and present it as a proposal without an evaluation [6]. A signature proves which writer produced a record. An agent that signs its own experiences will sign one written during a poisoned session too, so the signature must cover where the content came from, not just who stored it.

When memory reads and writes are tool or MCP calls through Intertrace, a memory-write tool can sit on an agent's ask list, new agents start in a learning period where consequential actions ask, and a script piped into a shell is classified as code execution whatever a memory recommended. Memory stores inside an agent's own process never cross the gateway, so provenance, namespaces and expiry belong in the store.

The test that separates deleting from containing

Seed one poisoned experience record in a dedicated namespace, start a fresh session with a similar legitimate task, and record whether the grafted step is attempted. Delete the source document and repeat. Then quarantine the derived record and repeat again. Only the second change should stop the behavior; if your runbook stops at the first, it closes incidents that come back. Around that core, check that a document asking the agent to save a procedural note makes the write ask, including with a delayed trigger word [2]; that one user cannot create a record a second user's session retrieves [3]; and that benign twins still work: a user explicitly saving a preference, a quoted security report containing hostile instructions, an ordinary task note. Re-run after every change to the memory pipeline, the model or the retrieval settings, across repeated runs.

Sources

Reporting, research and specifications this piece draws on. Links go to third-party sources; analysis and recommendations are Intertrace’s own.

  1. 01Spyware Injection Into Your ChatGPT's Long-Term Memory (SpAIware) · Embrace The Red (Johann Rehberger)
  2. 02Hacking Gemini's Memory with Prompt Injection and Delayed Tool Invocation · Embrace The Red (Johann Rehberger)
  3. 03Memory Injection Attacks on LLM Agents via Query-Only Interaction (MINJA, arXiv:2503.03704) · Dong et al.
  4. 04AgentPoison: Red-teaming LLM Agents via Poisoning Memory or Knowledge Bases (arXiv:2407.12784) · Chen et al.
  5. 05PoisonedRAG: Knowledge Corruption Attacks to Retrieval-Augmented Generation of Large Language Models · Zou et al., USENIX Security 2025
  6. 06MemoryGraft: Persistent Compromise of LLM Agents via Poisoned Experience Retrieval (arXiv:2512.16962) · Srivastava and He, 2025 preprint
  7. 07AI Agent Security Cheat Sheet · OWASP Cheat Sheet Series

About this desk

Intertrace Threat Research

Threat research

How attacks on AI agents work in practice, from public incidents and our own test corpora, and the controls that stop them.

All 18 pieces by Intertrace Threat Research

Dated October 7, 2026 · added to intertrace.ai October 17, 2026

+ Runtime enforcement

See these controls on your own agent traffic.

Intertrace sits inline between your agents and the models, tools and MCP servers they call, and decides every call before it runs.

Keep reading

All insights →