GhostApproval, explained — the symlink flaw that lets a malicious repo trick AI coding agents into writing outside your workspace
The human is still in the loop — the loop is just showing them the wrong file. GhostApproval hides a symlink inside a repo so that approving an edit to a harmless-looking 'project_settings.json' actually writes an attacker's SSH key into your login file. Cursor, Amazon Q, and Google Antigravity shipped fixes. Anthropic calls it outside Claude Code's threat model. Here's the mechanism, the version matrix, and what to actually do.
On July 8, 2026, the cloud-security firm Wiz disclosed GhostApproval: a flaw that lets a booby-trapped code repository steer six of the most popular AI coding agents — Claude Code, Cursor, Amazon Q Developer, Windsurf, Augment, and Google Antigravity — into writing attacker-controlled data outside the folder you opened. In the demo, that write is an SSH public key landing in ~/.ssh/authorized_keys, which hands the attacker a durable login to your machine. The trick underneath it is a symbolic link, a Unix feature older than most of the people reading this. The interesting part isn’t the symlink. It’s that the approval prompt — the human-in-the-loop safeguard these tools sell as their safety story — is showing you a different file than the one being written.
This page explains what GhostApproval does, why “just approve carefully” doesn’t fix it, exactly which agents are patched, and what to do — including the honest read on Anthropic’s decision not to patch Claude Code. Primary sources are at the end.
The 30-second version
- What it is. A malicious repo hides a symlink — a file named like something harmless (
project_settings.json) that actually points to a sensitive file elsewhere (~/.ssh/authorized_keys). Disclosed by Wiz, July 8, 2026. - What happens. The repo’s README tells the agent to add “a line” to
project_settings.json. That line is the attacker’s SSH key. The agent writes through the link into your real login file. Result: persistent SSH access for the attacker. - Why the prompt fails. The approval box names only
project_settings.json. In Wiz’s test, Claude Code’s own reasoning noticed the real target — the box just didn’t tell you. Wiz calls this an informed-consent bypass. - Who’s patched. Fixed: Cursor (v3.0), Amazon Q (language server 1.69.0), Google Antigravity. In progress: Augment, Windsurf. Declined: Anthropic Claude Code (“outside our threat model”).
- What to do. Update the fixed agents; don’t run any agent on an unreviewed repo; check clones for symlinks; sandbox untrusted code.
What the attack actually does
Strip away the AI and this is a 30-year-old Unix problem. A symlink is a file that transparently redirects to another path — write to the link, and the filesystem writes to the target. Wiz built a repository containing a symlink named project_settings.json that really points to ~/.ssh/authorized_keys, the file that lists the public keys allowed to SSH into your account:
ln -s ~/.ssh/authorized_keys project_settings.json
The repo’s README.md then does the social engineering: it instructs the assistant to “add a line” to project_settings.json for setup — and that line is the attacker’s own SSH public key, formatted to look like an innocuous config value. A developer who clones the repo and tells their agent to “set up the workspace” or “follow the README” gets exactly what they asked for, mechanically: the agent appends the line to project_settings.json, the filesystem follows the link, and the attacker’s key lands in authorized_keys. From that moment the attacker can log into the machine.
Wiz classifies the bug as symlink following (CWE-61) combined with UI misrepresentation (CWE-451). The first is the plumbing; the second is the actual vulnerability.
Why “approve carefully” is not a fix
Every one of these agents shows a confirmation prompt before writing a file. That’s the safety model: nothing hits disk without a human clicking approve. GhostApproval’s point is that the prompt lies by omission.
In Wiz’s test against Claude Code, the agent’s internal reasoning had already worked out that the target was a symlink to a sensitive settings file — the reasoning trace said as much. But the box presented to the developer read, in effect, “Make this edit to project_settings.json?” — naming only the harmless-looking file, not the ~/.ssh/authorized_keys that the write would actually reach. The human is still in the loop. The loop is just showing them the wrong thing. You can read every approval prompt like a hawk and still approve the attack, because the dangerous fact — this file is a redirect to your SSH keys — was the one piece the prompt left out.
And on some agents there is no meaningful prompt at all. Per Wiz, Windsurf writes the file to disk before the Accept/Reject buttons appear, so the prompt is an undo button after the fact. Amazon Q likewise offered only an “Undo.” Augment could perform silent reads and writes with no dialog. Where the write precedes the consent, the key is already in authorized_keys by the time you’re asked.
The version matrix
Wiz reported the flaw to all six vendors before publishing. Here is where each landed as of the July 8 disclosure:
| Agent | Status | Fix / identifier |
|---|---|---|
| Cursor | Fixed | v3.0 · CVE-2026-50549 (rated Critical) |
| Amazon Q Developer | Fixed | Language server 1.69.0 · CVE-2026-12958 (auto-updates) |
| Google Antigravity | Fixed | Patched · CVE pending |
| Augment | In progress | Acknowledged June 24, 2026 |
| Windsurf | In progress | Acknowledged June 23, 2026 |
| Anthropic Claude Code | Declined | ”Outside our current threat model”; closed as informative |
Two footnotes worth knowing. AWS’s bulletin also covers a separate Amazon Q flaw, CVE-2026-12957, where a poisoned repo could auto-load a config file and run commands to steal a developer’s AWS keys once the workspace was trusted — a reminder that “trust this folder” is a bigger grant than it looks. And Amazon’s language server “updates automatically unless the customer’s network configuration prevents it,” so air-gapped or proxy-locked setups should confirm they’re actually on 1.69.0.
The honest read on Claude Code
Anthropic is the one vendor that declined to ship a fix, and its reasoning deserves to be quoted rather than caricatured:
“This falls outside our current threat model. When the user first starts Claude Code in a directory, they must confirm that they trust the directory prior to starting the session. The scenario you describe involves a user explicitly confirming a permission prompt inside of a directory containing a malicious symlink, which falls outside of the Claude Code threat model.”
There’s a coherent argument in there: Claude Code makes you affirm trust in a directory before it does anything, so opening a malicious repo is, in Anthropic’s framing, already a decision you made. And Claude Code isn’t defenseless — it shipped a symlink warning in v2.1.32 (February 5, 2026), months before this report. So the picture is not “Claude Code is uniquely negligent.”
But the picture isn’t “nothing to see here” either. Wiz’s finding is narrow and specific: at the moment of the write, Claude Code’s approval UI named the wrong file while its own reasoning knew better. “You trusted the directory” answers a different question than “your consent prompt misrepresented the operation.” A developer who trusts a public repo enough to let an agent scaffold it is not thereby consenting to have their SSH keys rewritten — and the one surface that could have told them didn’t. Three of the six vendors treated that gap as a bug worth closing. Anthropic treated it as the user’s call. That’s a legitimate disagreement about where the trust boundary sits, and it’s exactly the kind of thing you want to know before you point Claude Code at a stranger’s code.
What to do
- Update the agents that fixed it. Cursor to v3.0+, Amazon Q’s language server to 1.69.0+ (confirm it if your network blocks auto-updates), Google Antigravity to current.
- Don’t point any agent at an unreviewed repo. The attack needs you to run the agent inside hostile code. Treat “clone a random repo and let the agent set it up” as the risky operation it is — most acutely on Claude Code, Windsurf, and Augment, which either won’t patch or hadn’t yet.
- Check clones for symlinks first.
git ls-files -sflags symlinks as mode120000;find . -type llists them. Asettings.jsonthat’s secretly a link to your home directory is the whole game. - Sandbox untrusted code. Run the agent in a container, VM, or dedicated user account with no access to your real
~/.ssh. This is the same hygiene that contains every other “the tool did something outside the folder” surprise — see what AI coding agents write to your disk and the CLAUDE.md attack surface, the other place a repo can smuggle instructions past you.
The real lesson
GhostApproval isn’t a clever new exploit; it’s a 1990s filesystem trick walking through a 2026 front door that was left open. The novelty is entirely in the interface. These agents earned their permissions model — write files, run commands, edit configs — by promising a human checkpoint. GhostApproval shows that a checkpoint is only as good as what it displays, and that “the user approved it” quietly becomes meaningless when the approval names the wrong file. That’s the same trust question the Claude Code ‘backdoor’ episode raised from the vendor side, now coming from the repo side: the tool will do exactly what it’s told, and told is doing a lot of load-bearing work. None of this means stop using coding agents — Claude Code is still the best agent for a lot of work. It means the boring rule holds: know what you’re running them on.
Companion reading
- What AI coding agents write to your disk — where these tools reach on your filesystem, and why “outside the workspace” matters
- The CLAUDE.md attack surface — the other way a repository injects instructions the agent obeys and you don’t see
- Claude Code’s ‘China backdoor,’ explained — the same trust boundary, tested from the vendor’s side
- Best AI coding agents, 2026 verdict — where each of these six lands once you weigh security against capability
Sources
- GhostApproval: A Trust Boundary Gap in AI Coding Assistants — Wiz
- GhostApproval Symlink Flaws Could Let Malicious Repos Run Code in AI Coding Agents — The Hacker News
- Bug in top AI coding agents shows that Unix-era security headaches never really die — The Register
- AI Coding Tools Tricked Into Hacking Developer Machine via Decades-Old Technique — SecurityWeek
- GhostApproval Flaw Hits Six Major AI Coding Assistants — Infosecurity Magazine
FAQ
What is the GhostApproval vulnerability?
A trust-boundary flaw Wiz disclosed on July 8, 2026, affecting six major AI coding agents. A malicious repo plants a symlink that looks like a harmless in-project file (e.g., project_settings.json) but points to a sensitive file outside the workspace (e.g., ~/.ssh/authorized_keys). When the agent follows a README instruction to edit that file, it writes through the link to the real target — while the approval prompt names only the harmless file. Wiz calls it an informed-consent bypass: you’re in the loop, but the loop shows you the wrong thing.
Is Claude Code affected, and did Anthropic fix it? Claude Code is one of the six vulnerable agents. Anthropic declined to patch, saying the scenario “falls outside our current threat model” because the user already confirmed they trust the directory; it closed the report as “informative.” Claude Code had shipped a symlink warning in v2.1.32 (February 5, 2026), but Wiz’s finding stands: its reasoning identified the real target while the confirmation box named only the innocuous file.
How does the symlink attack actually work?
The attacker commits a symlink — e.g., ln -s ~/.ssh/authorized_keys project_settings.json — so the file appears local but resolves to a sensitive target. The README tells the agent to add “a line” (the attacker’s SSH key) to project_settings.json. Ask the agent to “follow the README,” and it writes the key through the link into ~/.ssh/authorized_keys, granting persistent SSH access. It’s symlink following (CWE-61) plus UI misrepresentation (CWE-451).
Which agents are affected and which are patched? Vulnerable: Amazon Q Developer, Claude Code, Augment, Cursor, Google Antigravity, Windsurf. Fixed at disclosure: Cursor (v3.0, CVE-2026-50549), Amazon Q (language server 1.69.0, CVE-2026-12958), Google Antigravity. In progress: Augment, Windsurf. Declined: Claude Code. Some are worse — Windsurf writes before the Accept/Reject buttons appear, and Amazon Q offered only an “Undo.”
What should I do to protect myself?
Update the fixed agents (Cursor v3.0+, Amazon Q language server 1.69.0+, Antigravity current). For agents that won’t patch: don’t run agents on unreviewed repos; be wary of “follow the README” on unfamiliar code; check clones for symlinks (git ls-files -s shows mode 120000); and run untrusted code in a container or sandbox with no access to your real ~/.ssh.
Was this helpful?
Related reading
- Codex vs Claude Code usage limits in 2026 — same rules now, very different mileage
- Claude Code's 'China backdoor,' explained — what the hidden tracker actually did, which versions, and what to do
- Claude Tag, explained — what Anthropic's Slack agent does, who can use it, and the 65% claim worth reading twice
Reviews independently produced · Editorial policy
Read more reviews →