A file over 256KB let Claude Code Desktop leak your keys

Ask Claude to glance at a test coverage report, the kind of chore developers hand off every day, and the file could quietly ship your SSH keys and cloud secrets to a stranger's server. Noma Labs built exactly that chain inside Claude Code Desktop's preview pane and laid it out in Noma's writeup, and Anthropic scored it CVSS 8.7, or High.
At a glance
- The attacker never touches the victim's machine directly; they plant a padded HTML file in a public repository and wait for someone to clone it and ask Claude to read it.
- Files under 256 kilobytes render behind a policy that blocks scripts, but anything larger opens through a file:// address that got no such policy and can read the whole local disk.
- Anthropic's first patch on July 24 blocked the obvious reads, but Noma moved the same request into a background worker and slipped past it, forcing a second fix in August.
If you have not used it, the preview pane is the panel that pops up whenever Claude reads or edits an HTML file, showing the rendered result right away. The victim never opens a browser or clicks a URL; Claude renders the untrusted content on their behalf. And because Claude Code Desktop is an Electron app, that panel runs on a full Chromium engine with access to every standard web API.
A 500KB coverage report is the perfect disguise
To prove it out, Noma built a repository that looked like any other project, with source files, tests, and a coverage report. Testing tools generate those reports to show which parts of a codebase the tests touch, and they run large because they bundle source maps and CSS, so a 500KB file draws no suspicion. Noma pushed theirs past 256KB and tucked a JavaScript payload inside. A victim clones the repo, opens Claude Code Desktop, and asks a routine question, like which modules have coverage gaps. Claude reads the file, the preview pane renders it automatically, and the payload runs. No permission prompt appears, because the victim's own request to view the report is all it takes.
What the script pulled off the disk
Once running, the script works out the victim's home directory from the temp file path and starts pulling files through fetch() and XMLHttpRequest. On the list: SSH private keys, AWS access keys and secrets, npm and GitHub tokens, Kubernetes cluster credentials, Docker registry auth, and Git identity. It can also lift Claude's own OAuth tokens and the victim's real IP address through WebRTC. Then it ships everything to the attacker's server with navigator.sendBeacon(), a web API that fires a silent one-way POST in the background. Nothing on the machine restricts those outbound requests, so the transfer leaves no prompt the user would notice.
Why file size decided everything
The whole chain turns on one number. Files under 256KB load as data: URLs, which give the page an opaque origin and sit behind a content security policy that blocks scripts outright. Files over 256KB get written to a temp file and opened through a file:// URL instead, and in Chromium a file:// page can read other local files with fetch(). The policy that blocks scripts only ever covered the data: path, so a large file runs its JavaScript unchecked. There is also a filter meant to block file:// reads, but it only engages when the preview proxies a running dev server, like a local React app; rendering a static HTML file straight from disk leaves it switched off. Think of a guard who checks badges at the front desk but waves through anyone coming in the side door. Pad the file, skip the policy, walk past the filter.
The first patch, then a worker around it
Anthropic shipped a patch on July 24 that blocked fetch() and XMLHttpRequest calls to file:// paths from the main page. Noma got past it the same day. They moved the fetch into a Web Worker, a background script the browser runs on its own thread, spawned from a blob: URL, a context the filter never covered. The worker read the same files and handed them back to the main thread, which still shipped them out with sendBeacon(). All three original gaps stayed exploitable through that route, and on August 3 Anthropic confirmed the fix was incomplete and reopened the report.
One caveat on the facts: General Analysis says it has not reproduced the exploit or independently verified the patch, and notes the fixed-version claim comes from Noma's own report, with the GitHub advisory and CVE still pending. Black Duck's Ronald Lewis told CSO Online that relying on size thresholds or client-side filters for a security boundary is inherently fragile. On our view the 256KB line is the clearest example, since an attacker just pads the file past it.
When the CVE goes public
The complete fix landed on August 17 in Claude Desktop 1.30096.1 and later, delivered through auto-update, so a current client is covered. What is still outstanding is the paperwork: according to CSO Online, Anthropic is preparing a GitHub Security Advisory and has requested a CVE, both of which Noma lists as pending for October. Until those publish, the public record of what was fixed stays thin.
Up next
Anthropic's $16.8B quarter tops its whole 2025 revenue
Investors at Anthropic's San Francisco HQ on October 14 heard $16.8 billion in Q3 revenue, per Bloomberg sources. Its whole 2025 brought in roughly $4.6 billion. At what valuation would you buy into Anthropic's IPO?
Related stories
- One git call let a repo escape the Claude Code sandbox
- Stolen session keys are draining Claude Max accounts
- Breaking Claude Code Opus 5 Auto Mode
- Claude Opus broke four SAML libraries in a month
- Hidden China tracker pulled from Claude Code after exposé
- Auto mode let Claude Code run downloaded code in 6 of 10 tests
Comments
No comments yet. Be the first.
Join the conversation
Sign in to leave a comment. It appears after moderation.

