
Beyond Prompt Injection: Persistent Memory Poisoning in AI Agents
Forcepoint X-Labs details persistent memory poisoning, an attack where indirect prompt injection (e.g. hidden text in a webpage) tricks an AI agent into storing attacker-controlled facts, like a fake ABC Travel Support booking provider, in its long-term memory, so the poisoned content is later retrieved and trusted across unrelated future sessions. The article proposes a memory risk-scoring defense (source reputation, remember-this phrasing detection, new-contact or domain checks, contradiction detection, sensitive-category flags) and ships a working Python proof-of-concept comparing a vulnerable agent that blindly trusts extracted memory against a defended agent that scores and quarantines risky memory objects before use.
What it is
A Forcepoint X-Labs concept piece plus runnable Python PoC for persistent memory poisoning of memory-backed AI agents. The summary already names the attack and the five defensive signals; what it omits are the actual scoring weights, the decision thresholds, and the fact that the shipped PoC scores memory differently than the framework the article describes.
The scoring weights (framework)
The article's memory-risk engine sits as a gateway between memory extraction and long-term storage, and assigns additive risk points:
- Persistent-request phrasing ("Remember this", "For future requests", "From now on", "Always do this", "Make this your default"): +30
- New external contact/domain/vendor never seen by the org (e.g.
abc-travel-support.example): +30 - Contradiction with existing memory (e.g. official provider already = "Corporate Travel Portal"): +40, flagged "Memory Conflict Detected", held for user confirmation rather than overwriting
- Sensitive category modified (payment instructions, VPN config, banking, emergency contacts, vendor info, security contacts): +20, regardless of source
- Source reputation: tiered — internal wiki/docs = low, GitHub/Teams/Slack/Jira = medium, unknown webpage/anonymous doc = high
Memory objects are stored with metadata (trust_score, risk_score, classification, confirmed_by_user, source_type) so the memory is an inspectable object, not treated as truth.
The PoC scores differently
The runnable code does not implement the +30/+40/+20 framework above. Instead score_memory_risk() adds +25 per matched regex across four rules — authority_claim (official/approved/trusted/authorized), external_provider (provider/support/vendor/helpdesk/contact/booking), external_domain, urgent_action (urgent/emergency/immediately/always recommend) — plus +25 if confirmed_by_user is False, capped at 100. The defended_agent_answer() rejects any memory scoring ≥ 50 and redirects to the official channel. So an engineer reading the code should treat the article's weight table and the PoC as two separate designs; the PoC is a keyword/regex heuristic, not the described engine.
What to do
Treat every extracted memory as untrusted before storage or retrieval. The page's most reusable non-obvious recommendation beyond storage-time scoring is retrieval-time validation: re-evaluate memory when it is fetched, not only when written, to catch items that became conflicting or newly suspicious after storage. Other stated future directions: LLM semantic classification of medium/high-risk candidates, trust-graph inheritance, and full per-memory provenance/audit history.
Caveats
The author labels this explicitly a concept, "not a full-fledged attack scenario… likely to change," and the code "isn't production code." The regex extractor and keyword matcher are brittle by design — they demonstrate the mechanism, not a deployable filter.
Technologies named here
- BeautifulSoup
- Memory Risk Engine / Memory risk scoring
- Proof-of-concept Python simulation script
- Python
Techniques named here
- Persistent Memory Poisoning
- Indirect prompt injection
- Hidden-text injection in HTML
- Fake trusted-entity injection
Related in AI Security
