All postsLONG-FORM6 min read
Claude Code Security: What Can Your AI Agent Actually See?
Within five days, a fake Claude Code build on Cursor's marketplace and a fake cPGuard update both went hunting for keys. I built a fake-key lab to see what a bad tool inside an agent's shell can reach, audited my own pipeline, and wrote down five fixes in order of effort.
Within five days, two software updates went bad. One came through Cursor's extension store, dressed up as Claude Code. One came through the auto-update of a server security tool. Both went looking for the same thing: where the API keys and passwords live on the machine. My AI agents hold keys to my paid accounts, for voice, video and code, so I asked a simple question. If something bad ran inside my agent's shell, what could it actually see? I built a lab with fake keys to find out, then audited my own setup and fixed what I found.
Two updates, one week
On October 29, 2026, for about eleven hours (2:27 am to 1:35 pm PT), Cursor's extension marketplace served two fake builds of the Claude Code extension, versions 2.1.312 and 2.1.313, that Anthropic never made. Cursor says at most 5,000 users were affected, on macOS and Windows, and asks everyone to update to 2.1.314. David Dworken, who works on security at Anthropic, said no Anthropic systems were compromised and the official copies on the VS Code Marketplace and Open VSX were clean.
On November 2, at 02:06 UTC, someone used stolen credentials to push a fake update through cPGuard's update channel. cPGuard is OpsShield's security tool for Linux web servers. OpsShield says about 2,950 servers installed it between 02:08 and 03:20 UTC, and it ran as root, the admin account that can read anything on the server.
Both attacks rode an update channel people already trusted.
What they went looking for
Environment variables are the heart of this. When a guide tells you to paste an API key into your shell profile, every program you start from that terminal gets a copy: your editor, your build tools, every package script, every extension running inside them.
Microsoft took the fake extension apart. As soon as it loaded, it searched environment-variable names for _KEY, TOKEN, SECRET, PASS, AWS and GCP, and sent back up to forty of those names, with the username, home folder and git email. Microsoft says the names went out and the values stayed behind. That's a shopping list. It also tried to plant its own SSH login key and open a back door, and it left scripts that keep retrying in the background. Cursor says the back door would fail to open on most machines, but the key and those scripts can still be left behind, so it asks everyone affected to check, clean up and replace their keys.
The cPGuard update went further. It read password hashes, root's SSH keys, the database root password, root's shell history and, on a small number of servers, cloud storage keys.
An agent like Claude Code or Codex runs commands as you. It inherits your environment, opens your files and installs packages. Anything bad that runs inside that session sees what the agent sees.
The lab
A throwaway folder with a fake project, a fake home folder and fake keys. A tiny helper program stands in for a tool you installed, or a command your agent runs. It sends no data anywhere: it counts what it can reach with Microsoft's name pattern and tries one empty connection to the internet. Measured on my Mac on November 5, 2026 (macOS 26.7.1, Python 3.9.6).
| Run 1: keys exported | Run 2: nothing exported | Run 3: run 2 + sandbox profile | |
|---|---|---|---|
| Key names found | 5 | 0 | 0 |
| Key values readable | 5 | 0 | 0 |
| .env file | readable | readable | blocked |
| SSH key (fake) | readable | readable | blocked |
| Cloud keys (fake) | readable | readable | blocked |
| Internet | reachable | reachable | blocked |
Run 2 cost nothing. Run 3 took one small macOS sandbox profile: deny reads of the two key folders and the .env file, deny outbound network. Don't hand every program your keys, and fence off the places keys live.
My own setup
I'm not publishing key names or file locations, but here's what the audit found. My overnight agent, the one that builds these episodes, kept the keys out of its own environment: they loaded only inside small wrapper scripts for one command, and deny rules (settings that list files the agent may not open) covered the key file.
The weak part: seven of my scripts read one shared key file, and two of them loaded every key in it to use exactly one. One key had full access to its account when the job needed a couple of permissions. It was set to expire after thirty days, which helped. Expiry limits how long a leaked key works; scope, the list of things a key may do, limits what it can do.
What I changed: each job gets its own key, scoped to that job, with an expiry and a spending cap where the service offers one. Each script loads only the key it needs. The agents run inside the sandbox with deny rules on top, because a deny rule matches a file by its name, and a script that reaches the file another way can slip past it. A sandbox that blocks the whole folder stops both.
Five fixes, in order of effort
The order is my opinion.
- Stop exporting keys in your shell profile. Load a key only for the command that needs it, with a password manager's command line tool or a small script that reads the key and starts only that program. Run 2 shows what it buys.
- Scope every key and give it an expiry. Many AI and cloud services let you limit a key to certain actions, and many let you set a spending cap. A leaked key with a $10 cap is a bad day; a leaked key with no cap can be a much worse month.
- Turn on the sandbox. In Claude Code it's off by default; type
/sandbox. Out of the box it blocks writes outside your project and fences the network: allowed websites start empty, and a new website is prompted, refused, or (with permission prompts switched off) let through, depending on your permission mode. The docs also say the default "still allows reading credential files", and sandboxed commands inherit Claude Code's environment, so list your key folders and secret variables insandbox.credentials. On native Windows, commands run unsandboxed; use WSL2. - Slow down updates for tools that touch your code. Microsoft's advice after this attack: allow extensions only from approved publishers and use an install cooldown. The fake was published under the real Claude Code extension name, so in my opinion the cooldown is what would have helped here: a bad version pulled after eleven hours never reaches you if you wait a couple of days.
- Write your rotation list now. Which keys exist, where to cancel each one, and in what order. Both vendors say to reset and rotate from a machine you trust.
Did it hit you?
- Cursor + Claude Code extension, October 29: update to 2.1.314, look for an SSH key labelled
svc-telemetryand follow Cursor's notice and cleanup script. Uninstalling the extension alone may not be enough. - cPGuard: update to 5.88.25 or later and check the install log for versions 5.88.12 to 5.88.19. If you find one, treat the server as exposed and rotate everything on it. OpsShield warns that a clean log doesn't prove the server is safe.
The takeaway
Your agent is you, with fewer second thoughts. Whatever it can read, anything that runs inside it can read too. My opinion: the fix that pays off most is boring. Fewer keys in reach, smaller keys, and a fence around the folders where they live.
Where do your API keys live right now? Tell me on the video.
Daily email
Get each breakdown in your inbox.
One email each evening, right after the Short goes live: the AI tool it covers, the full write-up with sources, and how to get paid for it. Free, and you can unsubscribe anytime.
Sources
- Cursor, Claude Code extension security notice (Oct 29, updated Oct 30): https://cursor.com/blog/claude-code-extension-security-notice
- Cursor on X, Oct 30: https://x.com/cursor_ai/status/2116074289053175808
- David Dworken on X, Oct 30: https://x.com/ddworken/status/2116178850032066572
- Microsoft Security Blog, Oct 30: https://www.microsoft.com/en-us/security/blog/2026/10/30/inside-malicious-claude-code-branded-cursor-extension-persistent-ssh-backdoor/
- OpsShield advisory: https://opsshield.com/notice/cpguard-update-channel-compromise.html
- OpsShield disclosure, Nov 3: https://opsshield.com/notice/security-incident-disclosure-servermanage.html
- Claude Code docs, sandboxing: https://code.claude.com/docs/en/sandboxing
- Claude Code docs, settings: https://code.claude.com/docs/en/settings
This is general security hygiene from my own setup, not a professional security audit.