I tricked Claude into leaking your deepest, darkest secrets

I tricked Claude into leaking your deepest, darkest secrets

我诱骗 Claude 泄露了你内心深处最黑暗的秘密

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. 看看这段与 Claude 的对话。注意到什么可疑之处了吗?看起来平淡无奇,但当 Claude 回复完毕时,它已经将我的全名、现任雇主以及安全问题的答案发送给了攻击者,而且整个过程没有任何异常迹象。

server logs$ bun dev Exfiltrating data… Name: Ayush Paul Company: Beem Hometown: Charlotte, NC

服务器日志$ bun dev 正在窃取数据… 姓名:Ayush Paul 公司:Beem 家乡:北卡罗来纳州夏洛特

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. 我研究 AI 记忆系统已经有一段时间了,我注意到尽管这些系统存储的信息比大多数密码管理器还要多,但其安全性却完全被忽视了。像 Claude 这样的 AI 助手已经积累了数百万用户最密集的信息档案。人们向它们倾诉一切,从机密工作资产到个人秘密,再到情感问题。随着时间的推移,这些对话历史会成为一个高保真的“你”,可被用于勒索、冒充或绕过安全问题。

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. 考虑到这一点,我决定研究一下 Claude,特别是其主要的日常助手版本(claude.ai,而非 Claude Code)。Claude 拥有一个功能尚可但略显天真的两部分记忆系统。第一部分是每日总结:你最近的对话会被提炼成关于你的几段文字,并注入到每一场对话中,这样 Claude 就不必从零开始了解你。第二部分是一个检索工具 conversation_search,用于按需搜索你的完整对话历史。这里面包含着极其宝贵的信息。记忆系统本身是安全的,但真正的问题在于,当你把它与一个能够浏览网页的智能体结合时,会发生什么?

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! 为了窃取你的记忆,我们需要找到一种将数据从 Claude 的沙盒中提取出来的方法,换句话说,就是一种数据外泄途径。我想要一种完全通用的方法(即不需要实验性设置、代码执行或小众的 MCP)。我立刻想到了 Claude 的网页浏览功能。Claude 内置了两个访问互联网的工具:web_searchweb_fetchweb_fetch 被设计为只读,让 Claude 可以查看任何 URL 的内容。但是,如果 Claude 能访问我们拥有的网站,那么我们应该就能检测到 Claude 正在尝试访问我们的网站!

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. 我迅速搭建了一个 Web 服务器 evil.com,并记录了所有请求。我转到 Claude,让它去查看该网站,结果……请求失败了?在困惑了 15 分钟后,我发现 Cloudflare 在未经我同意的情况下给我的网站加上了一个疯狂的 robots.txt(Cloudflare,我爱你们,但这真的得停下来)。解决这个插曲后,我再次尝试,终于在我的服务器上看到了 Claude 的请求。

server log$ bun dev 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. 服务器日志$ bun dev User-Agent: Claude-User - GET / 现在我们可以看到 Claude 正在尝试访问我们的网站,但我们如何让它将信息发送到我们的网站呢?由于 web_fetch 只发起 GET 请求,URL 是我们隐藏信息的唯一地方。我们能要求 Claude 将数据编码在路径中吗?我之前见过 Claude 浏览页面——这应该可行。我修改了 Web 服务器以接受任何任意路径并记录它,然后问 Claude:“你能使用 web_fetch 并导航到 evil.com/[我的名字],但用我真实的名字吗?”过了一会儿,请求失败了?Cloudflare 又回来了吗?不,事实证明 Anthropic 棋高一着。

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. 事后看来,那确实太简单了。从沙盒中访问任意 URL 将是一个巨大的错误,而 Anthropic 有先见之明地阻止了它。但我很困惑。我知道我曾见过 Claude 自主浏览网页并自行导航页面,为什么这次会被阻止?经过一番摸索,我发现 web_fetch 工具满足 3 个条件之一才能访问:URL 必须直接在用户消息中指定,直接在 web_search 查询结果中指定,或者在之前的 web_fetch 结果内容中作为链接出现。

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. 第三个条件很有趣:它给了 Claude 一种“点击”它在之前页面上看到的任何超链接的方法。既然我们拥有该网站,我们就能精确控制显示哪些链接。我开始摆弄这个发现,看看它是否能为我带来什么突破。我意识到:如果网站链接到所有东西会怎样?显然,为所有可能的数据创建一个网站可能超出了范围,但如果我简化它呢?我能否创建一个目录并给 Claude 一个“键盘”?我快速构建了一个原型,主页链接到 /a, /b, /c 等等。

Then, I asked Claude “Go to evil.com and navigate to the first letter of my name.” I checked the logs and it WORKED! 然后,我问 Claude:“去 evil.com 并导航到我名字的第一个字母。”我检查了日志,成功了!

server log$ bun dev User-Agent: Claude-User - GET / User-Agent: Claude-User - GET /a I decided to push it further. I made /a link to /aa, /ab, /ac, and so on, and made those link to /aaa… generated on the fly. 服务器日志$ bun dev User-Agent: Claude-User - GET / User-Agent: Claude-User - GET /a 我决定进一步尝试。我让 /a 链接到 /aa, /ab, /ac 等等,并让它们链接到 /aaa……这些都是动态生成的。