Back to Theory
Theory7 min read · July 15, 2026

Memory and Context Poisoning Is Now OWASP ASI06 — What Builders Need to Know

OWASP added Memory and Context Poisoning as ASI06 in 2026, formally recognizing that poisoned agent memory persists across sessions in a way prompt injection never did. Here's what builders need to defend against it.

F
Feather DB
Engineering

Memory and Context Poisoning is the point where an agent's greatest asset — persistent memory — becomes its biggest liability. An attacker doesn't need to break your model or steal your keys. They just need one malicious entry to survive the write into long-term memory, and every future session inherits it. In 2026, OWASP gave this problem a name and a number: ASI06, in the Top 10 for Agentic Applications. That's a signal worth taking seriously if you're shipping agents with persistent memory.

What memory poisoning actually is

Memory poisoning is a persistent attack against an agent's long-term memory store. An attacker writes malicious content into memory — through a user message, a scraped document, a tool response, or another agent's output — and the agent later retrieves and acts on that content as if it were legitimate, trusted information. Vectorize's breakdown of the attack and Christian Schneider's research on persistent memory poisoning both converge on the same structural point: this is not the same failure mode as prompt injection.

Prompt injection is a single-session attack. Malicious instructions hide in a document or web page, the model reads them, does something wrong, and the session ends. Reset the context and the attack is gone. Memory poisoning breaks that assumption entirely. The malicious content gets written to persistent storage, and it survives the session boundary. An instruction planted today can sit dormant for weeks and then execute when a completely unrelated future interaction happens to retrieve that memory entry. The attack and its effect are temporally decoupled — which means by the time the bad behavior shows up, the actual injection point is long gone from your logs, your review window, and probably your memory of what happened that week.

That decoupling is what makes it structurally worse than prompt injection, not just a variant of it. You can't catch it by reviewing the session where the damage happened, because that's not the session where the attack occurred.

Why OWASP made it ASI06, not just another prompt-injection subtype

OWASP's Top 10 for Agentic Applications already had prompt injection covered. Folding memory poisoning into that category would have implied the same defenses apply. They don't. OWASP's addition of Memory and Context Poisoning as ASI06 is a formal acknowledgment that agentic systems introduce a new class of risk: persistent state that the agent trusts by default, updated continuously, with no inherent mechanism for distinguishing a legitimate memory update from a hostile one.

This matters for anyone architecting agent memory today, because it reframes the design question. It's not "how do we sanitize inputs before the model sees them" — that's the prompt-injection playbook. It's "how do we decide what's allowed to become a permanent belief the agent carries into every future interaction, and how do we know when that belief has been tampered with." Those are storage-layer and governance questions, not just input-filtering ones.

The numbers behind the threat

The attack isn't theoretical. Reported attack success rates against LLM-based agent implementations in 2026 research run from 80% up to 95%, with some studies reporting rates as high as 99.8% under favorable conditions for the attacker, per recent analysis of memory as an attack surface. MINJA — a memory injection attack studied specifically against production-style agent memory — reports injection success rates over 95% against production agents in its evaluation.

Those aren't lab-only edge cases against toy setups. They're results against agents built the way most teams are actually building them right now: write-then-trust memory pipelines with no provenance tracking and no separation between "the user told me this" and "I inferred this and I'm now treating it as fact."

Defenses that actually address the persistence problem

Standard input sanitization doesn't solve this, because the problem isn't just what enters the model's context window in one turn — it's what gets permanently written to storage and retrieved in every future turn. Three primitives show up repeatedly in current defense research:

  • Memory contracts — explicit, enforced rules for what an agent is allowed to store as a durable belief. Not every user statement should become a persistent memory entry. A contract defines the boundary: facts about the user's stated preferences might qualify; unverified claims about the world, or instructions embedded in retrieved content, should not write to long-term memory without a separate verification step.
  • Context provenance tracking — recording where every memory entry came from: direct user input, a tool call result, scraped web content, or another agent's output. Provenance lets you apply different trust levels at retrieval time instead of treating every stored memory as equally authoritative.
  • Belief-drift detection — monitoring when a stored "fact" changes in a way that doesn't match a legitimate update pattern. A user correcting their own stated preference is normal drift. A memory entry silently flipping from "never send payment confirmations without 2FA" to "send payment confirmations automatically" between sessions, with no corresponding user action, is not.

One detection system cited in recent research layers five checks — including prompt-injection screening and secret/PII leakage detection — on top of memory writes, and reports 92.5% recall, 100% precision, and zero false positives in its own evaluation. That's a useful reference point for what a layered approach can achieve, though it's one system's self-reported numbers, not an industry benchmark.

A minimal provenance-tagging pattern looks something like this at write time:

def write_memory(store, content, source, confidence):
    # source: "user_direct" | "tool_output" | "scraped_web" | "agent_inferred"
    trust_tier = TRUST_MAP.get(source, "untrusted")
    store.upsert(
        content=content,
        metadata={
            "source": source,
            "trust_tier": trust_tier,
            "written_at": now(),
            "verified": trust_tier == "trusted",
        },
    )

def retrieve_for_context(store, query, min_trust="trusted"):
    return store.query(
        query,
        filter={"trust_tier": {"$in": trust_tiers_at_or_above(min_trust)}},
    )

The logic here is ordinary: tag content by where it came from, and let retrieval-time filtering decide what the agent is allowed to treat as fact for a given action. Content from scraped web pages or third-party tool output starts at a lower trust tier than content the user stated directly, and low-trust entries don't get promoted to "belief" status without an explicit verification step.

Where Feather DB fits — and where it doesn't

To be direct about this: Feather DB does not ship a built-in memory-poisoning or prompt-injection detector today. Neither do most memory systems in production right now. This is an application-layer problem, and pretending a vector store solves it by default would be dishonest.

What Feather DB does provide is the storage substrate that the defenses above are built on top of. Namespace isolation lets you separate memory scopes — per user, per agent, per trust boundary — so a poisoned entry in one namespace doesn't automatically become retrievable context in another. Metadata filtering lets you implement exactly the kind of trust-tier and provenance tagging shown above, querying only memories that meet a minimum trust threshold before they enter an agent's context. Those are primitives, not a finished defense. The memory contract, the provenance rules, and the belief-drift monitoring are still work you have to design and own.

FAQ

Is memory poisoning just a form of prompt injection?

No. Prompt injection is confined to a single session and resets when context clears. Memory poisoning writes malicious content into persistent storage, so it survives across sessions and can trigger long after the original injection point, per research on persistent memory poisoning in AI agents. That's why OWASP treats them as distinct categories.

Can I just sanitize user inputs and be done with it?

Sanitizing inputs helps against prompt injection but doesn't address memory poisoning on its own, because the risk isn't limited to what the model reads in one turn — it's what gets permanently written to memory and retrieved in every future turn. You need write-time controls (memory contracts, provenance tagging) and ongoing monitoring (belief-drift detection), not just input filtering.

Does Feather DB detect or block poisoned memory entries automatically?

No. Feather DB has no built-in memory-poisoning detector as of today. It provides namespace isolation and metadata filtering, which you can use to build provenance tracking and trust-tiered retrieval yourself. The detection and enforcement logic is your application's responsibility.

What's the first defense to implement if I'm already shipping agent memory?

Start with provenance tagging at write time — record where every memory entry came from before you worry about detection models. Once every entry has a source and trust tier, you can filter retrieval by trust level immediately, which closes off the most common attack path: untrusted content silently promoted to trusted belief.

If you're building persistent memory into an agent and want the namespace and metadata primitives to build provenance tracking on top of, pip install feather-db and see how the pieces fit.