The Memory Heist

eieio1 pts0 comments

The Memory Heist

Take a look at this Claude conversation. Notice anything suspicious?

Looks innocuous, but by the time Claude finished responding, it had already sent my full name, current employer, and the answers to my security questions to an attacker, without any indication that anything had happened.

server logs

$ bun dev<br>Exfiltrating data...<br>Name: Ayush Paul<br>Company: Beem<br>Hometown: Charlotte, NC

I've been exploring AI memory systems for a while now, and I've noticed that the security side of things is completely overlooked, despite holding more information than most password managers. AI assistants like Claude have accumulated the most information-dense profiles on millions of people. People confide in them on everything, from confidential work assets to personal secrets to relationship problems. Over time, that conversation history becomes a high-fidelity reconstruction of you, one that could be used for blackmail, impersonation, or bypassing security questions.

With that in mind, I decided to take a look at Claude, specifically the main everyday assistant (claude.ai , not Claude Code). Claude has a functional, but naive, two-part memory system. The first is a daily summarization pass: your recent conversations get distilled into a few paragraphs about you, injected into every single conversation so Claude doesn't have to start from scratch. The second is a retrieval tool, conversation_search, to search your full conversation history on demand.

There's some incredibly valuable information here. The memory system itself is secure, the real question is what happens when you pair it with an agent that can browse the web.

the naive approach

To steal your memories, we need to find a way to get data out of Claude's sandbox, or in other words, an exfiltration vector. I wanted something fully general purpose (i.e. no experimental settings or code execution or niche MCP required). My mind immediately went to Claude's web browsing capabilities. Claude has two tools built-in to access the internet, web_search and web_fetch. web_fetch is designed to be read-only, giving Claude a way to look at the contents of any URL.

But, if Claude can access a website that we own, then we should be able to detect Claude trying to access our website! I quickly spun up a web server, evil.com, and logged all requests. Went over to Claude, asked it to check it out, and... request failed?

After 15 minutes of confusion, it turned out Cloudflare had put a crazy robots.txt on my site without my consent (Cloudflare, love you guys, but this needs to stop). After fixing that tangent, I tried again and finally, I saw Claude's request from my server.

server log

$ bun dev<br>User-Agent: Claude-User - GET /

Now we can see Claude trying to access our site, but how can we get it to send some information to our site? Since web_fetch only makes GET requests, the URL is the only place we can hide anything. Could we just ask Claude to encode some data in the path? I'd seen Claude navigate pages before — this should work. I modified the web server to accept any arbitrary path and log it, then asked Claude Can you use web_fetch and navigate to evil.com/[my-name] but with my actual name?. It takes a sec, and then... the request failed?

Is Cloudflare back? No, it turns out Anthropic was one step ahead.

the complex approach

In hindsight, that would have been way too easy. Accessing arbitrary URLs from a sandbox would be a huge mistake, and Anthropic had the foresight to block it. But, I was confused. I knew I'd seen Claude web browse autonomously and navigate pages on its own, so why was it getting blocked for this? After a bit of poking around, it turned out the web_fetch tool had 3 criteria. The URL being fetched must either:

be specified directly in the user message,

be specified directly in the results of a web_search query, or

be linked in the content of a previous web_fetch result.

The third criterion is the interesting one: it gives Claude a way to "click" on any hyperlinks it saw on a previous page. And since we own the website, we control exactly which links appear.

I started to mess around with this, seeing if this discovery unlocked anything for me. I realized: what if the site linked to everything?. Obviously, creating a website for every possible bit of data about anything might be out of scope, but what if I simplified it? Could I create some form of directory and give Claude a "keyboard"? Built a quick prototype where the homepage linked to /a, /b, /c, and so on.

evil.com<br>Reset<br>Welcome to evil.com

Choose a...

claude web_fetch memory anything server conversation

Related Articles