system: OPERATIONAL
← back to all hacks
AGENTS CRITICAL NEW

mem0 and OpenMemory: unauthenticated APIs expose agent memory and keys

Two flaws disclosed July 7, 2026 (VulnCheck, up to 9.8 critical) let anyone read, write or delete an LLM agent's stored memories, and pull provider API keys or pivot via SSRF — no authentication required.

2026-07-21 // 6 min affects: mem0, openmemory, llm-agent-memory, rag-pipelines, ollama

What is this?

On July 7, 2026, VulnCheck published two advisories for mem0 and its self-hosted OpenMemory API — a widely deployed “memory layer” that lets LLM agents store and retrieve long-term context across sessions. Both are the same class of bug: missing authentication for a critical function (CWE-306). The affected API routers ship without any authentication middleware, so anyone who can reach the service can operate it. One flaw exposes the memory store; the other exposes the configuration API. The project fixed both in commit a3154d5. Assigned severities run from 9.2 to 9.8 (critical) — network-reachable, no privileges, no user interaction.

This matters because a memory backend is not a cache; it is trusted context that an agent reads back and acts on. Breaking its integrity or confidentiality breaks the agent.

How it works

There are two independent weaknesses, each reachable without credentials.

The memory API registers its routers with no auth guard. An unauthenticated caller can supply an arbitrary user_id and read, write, or delete any user’s memories, or hit a pause endpoint with global_pause=true to stop memory operations for every user — a denial-of-service against the whole deployment.

The config API is worse for lateral movement. A GET on the config endpoint returns stored provider secrets — for example OpenAI keys — in plaintext. A PUT to the LLM config lets an attacker set the ollama_base_url value to an internal address such as a cloud metadata service, turning the server into a server-side request forgery primitive that reaches resources the attacker cannot reach directly.

Untrusted network
      |
      v
[ mem0 / OpenMemory API ]  <- no auth middleware on routers
   |            |
   |            +-- GET  config      -> provider API keys in plaintext
   |            +-- PUT  llm config  -> ollama_base_url = internal host -> SSRF
   |
   +-- read/write/delete memories (arbitrary user_id)
   +-- pause (global_pause=true)     -> denial of service

No exploit code is reproduced here; the endpoints above are described only at the level already documented in the public advisory. The point is architectural: the memory service assumed it sat on a trusted network and enforced nothing itself.

Why it matters

Write access to memory is a persistent injection channel. Unlike a one-shot prompt injection, a poisoned memory is retrieved again and again, surviving across sessions — the durable version of agent memory poisoning. Read access is a straightforward data leak of everything the agent chose to remember: conversation history, personal data, and business context. The config leak hands an attacker live LLM API keys (billing abuse and model access), and the SSRF path can escalate into cloud credential theft via metadata endpoints.

The exposure surface is large because these services are frequently bound to 0.0.0.0 or dropped onto an internal network on the assumption that “internal” means “trusted.” Internet-wide scans keep showing that assumption is wrong — hundreds of thousands of AI services sit exposed. This is the same backend-not-model failure pattern seen across the agent tooling stack: the interesting break is in the plumbing, not the prompt.

Defenses

Update mem0 past the fix commit first; the patch adds the missing authentication. Beyond patching, treat the memory layer as a real service with a real trust boundary.

Do not expose memory or config APIs to untrusted networks — bind to localhost or place them behind an authenticated gateway, and segment them away from the open internet. Enforce authentication and authorization in the service itself, and derive user_id from the authenticated principal server-side rather than trusting a client-supplied value, so one tenant cannot address another’s memories. Keep provider credentials out of a plaintext config store: use a secrets manager and restrict config endpoints to administrators. Add SSRF controls on any URL the config accepts — allowlist permitted hosts, block link-local and metadata ranges such as 169.254.169.254, and disable IMDSv1. Finally, apply defense in depth on the read path: treat retrieved memories as untrusted input, tracking provenance so a poisoned entry cannot silently drive a tool call — the same instinct behind the lethal trifecta framing of private data, untrusted content, and an exfiltration path.

Status

ItemReferenceDateNotes
Unauthenticated memory access (read/write/delete, DoS)CVE-2026-59705 (VulnCheck)2026-07-07CVSS 9.8 critical; arbitrary user_id, global_pause DoS
Plaintext key exposure + SSRF via config APICVE-2026-59706 (VulnCheck)2026-07-07CVSS 9.3 / 9.2; ollama_base_url SSRF, CWE-306
Fixmem0 commit a3154d52026-07Adds authentication to affected routers

The lesson is old and keeps repeating in the agent era: a memory layer is a security boundary, not an implementation detail. If it authenticates nothing, an attacker can rewrite what your agent believes, read what it knows, and steal the keys it runs on — all before a single prompt is exchanged.

Sources