Articles
The GhostApproval Vulnerability: What It Means for Your AI Coding Toolchain
A symlink bug in major AI coding assistants showed a harder truth: approval prompts only help when they tell the user what will really happen.
On July 8, 2026, Wiz published research on a vulnerability pattern across six AI coding assistants: Amazon Q Developer, Anthropic Claude Code, Augment, Cursor, Google Antigravity, and Windsurf. The flaw, named GhostApproval, lets a malicious repository trick an agent into writing outside its workspace sandbox. In the worst case, that can turn into remote code execution on the developer's machine.
The trick is a symlink. Old Unix machinery. The uncomfortable part is not the symlink itself. It is that the approval prompt, the thing the user is supposed to trust, can show a harmless-looking path while the agent writes somewhere else.
How the Attack Works
The attack chain is short:
1. Attacker creates a repository with a symlink:
project_settings.json -> ~/.ssh/authorized_keys
2. README.md contains instructions:
"To set up the workspace, add the following line
to project_settings.json..."
3. Developer clones the repo and asks their AI assistant
to "set up the workspace" or "follow the README"
4. The agent resolves the symlink internally but presents
the user with: "Make this edit to project_settings.json?"
5. User approves. The write goes through the symlink
directly into ~/.ssh/authorized_keys.
6. Attacker now has passwordless SSH access to the machine.
The core of the exploit maps to two CWEs:
- CWE-61 (UNIX Symbolic Link Following): the agent follows a symlink without validating that the resolved path is within the workspace boundary.
- CWE-451 (User Interface Misrepresentation of Critical Information): the approval dialog shows the symlink name, not the true target path. The user cannot make an informed decision.
Three Attack Variants
Wiz demonstrated three exploitation paths:
SSH key injection. A symlink to ~/.ssh/authorized_keys dressed as a config file. The attacker's public key is formatted as a benign-looking setting. One approval grants persistent remote access.
Shell startup hijacking. A symlink to ~/.zshrc or ~/.bashrc. The injected line runs attacker code every time a terminal opens. This persists across reboots and survives the removal of the malicious repo.
Credential theft via read. In the Augment variant, the agent read AWS credential files outside the project scope without any approval prompt, exfiltrating secrets through the model's context window.
The "Knowing But Hiding" Problem
The worst part is not that agents followed symlinks. It is that some agents appeared to understand the risk while still showing the user a clean-looking approval prompt.
During testing of Claude Code, the agent's internal chain-of-thought reasoning explicitly stated:
"I can see that
project_settings.jsonis actually a zsh configuration file."
Yet the confirmation prompt displayed to the developer simply asked: "Make this edit to project_settings.json?"
The agent had better context than the user. The prompt threw that context away.
As Wiz researchers stated: "Human in the loop only protects you if the loop tells the truth."
The Windsurf Variant: Write-Then-Confirm
Windsurf exposed an even worse pattern. The agent wrote changes to disk before displaying the confirmation dialog. The approval prompt was not a gate. It was an undo button. By the time the user saw the prompt, the attacker's SSH key was already in authorized_keys.
That is not approval. It is theater. A confirmation dialog that appears after the write gives the user the feeling of control without the control.
Affected Tools and Patch Status
| Vendor | Severity | CVE | Patched Version | Status | |--------|----------|-----|-----------------|--------| | Amazon Q Developer | High | CVE-2026-12958 | 1.69.0 (May 27) | Fixed | | Cursor | Critical | CVE-2026-50549 | 3.0 (June 5) | Fixed | | Google Antigravity | Critical | Pending | 1.19.6 (May 22) | Fixed | | Augment | Critical | N/A | TBD | In progress | | Windsurf | Critical | N/A | TBD | Acknowledged, no fix | | Claude Code | High | CVE-2026-39861 | 2.1.64 (April 20) | Fixed |
Claude Code's timeline is worth noting separately. A related symlink sandbox escape (CVE-2026-39861, CVSS 7.7) was reported via HackerOne, patched in version 2.1.64 on April 20, and published as GHSA-vp62-r36r-9xqp. Anthropic initially disputed the Wiz report as "outside our threat model," arguing the developer consented both by trusting the directory and by approving the prompt. They later noted that symlink warnings shipped in early February as "routine hardening." Current versions (2.1.173+) resolve symlinks and warn users before writing to sensitive paths.
Disclosure Timeline
| Date | Event | |------|-------| | February 10, 2026 | Wiz discovers the vulnerability pattern | | February 12-15, 2026 | Reports submitted to vendors; Anthropic responds with rejection | | February 24-March 5, 2026 | Remaining vendors acknowledge receipt | | April 20, 2026 | Claude Code CVE-2026-39861 patched (2.1.64) | | May 22, 2026 | Google deploys fix (Antigravity 1.19.6) | | May 27, 2026 | AWS deploys fix (Amazon Q 1.69.0) | | June 5, 2026 | Cursor deploys fix (v3.0) | | June 23, 2026 | Windsurf acknowledges; no further update since | | July 8, 2026 | Public disclosure by Wiz |
Why This Matters Beyond the Specific Bug
GhostApproval is not only a symlink bug. It shows where the usual AI coding assistant safety story breaks down: "the user approves each action."
That story depends on the prompt telling the truth. But the prompt is generated by the same system that is about to do the work. No independent process confirms that the displayed path matches the resolved path. No separate observer checks that the write stays inside the workspace before bytes hit disk.
Security teams have seen this pattern before. You do not let the application be the only judge of its own behavior. You add outer checks: sandboxes, mandatory access controls, network policy, external monitoring.
The Pattern Repeats
Consider what GhostApproval reveals about the assumptions in today's AI coding tool security:
What a Fix Actually Looks Like
The vendor patches address the immediate symlink issue with three approaches:
- Resolve before display: Resolve all symlinks in a path before showing the confirmation prompt, so the user sees the true target.
- Boundary check after resolution: After symlink resolution, verify the canonical path is within the workspace. Block or warn if it is not.
- Never write before confirmation: Ensure the confirmation gate fires before any bytes hit disk - not after.
These fixes are necessary. They also fix one class of bug, not the deeper issue: the agent still reports its own planned action, and the user is still the only visible verification point.
The Structural Gap
GhostApproval works because many assistant flows have one practical trust boundary: the approval prompt. Everything before that prompt is trusted implicitly: context assembly, symlink resolution, path display. Everything after it runs with the developer's local account.
What is missing is an independent layer that:
- Observes what the agent actually does (file writes, network requests, shell commands) separately from what the agent claims it will do
- Validates that the target of a file operation matches what was approved, using filesystem-level monitoring rather than self-reported paths
- Records approvals with enough context (resolved paths, timestamps, session lineage) to audit whether consent was truly informed
- Enforces policy at the network level by intercepting model API requests and responses, so even a compromised or misbehaving agent has to pass through an independent checkpoint
That is the difference between a safety feature inside the tool and a security control around the tool. If the tool is confused by a repository, its internal safety features can be confused too. External observation has a better chance because it sits outside the agent process and outside that trust domain.
Immediate Actions
If you or your team uses AI coding assistants:
-
Update immediately. Cursor 3.0+, Amazon Q 1.69.0+, Claude Code 2.1.64+, and Antigravity 1.19.6+ contain fixes. If you use Augment or Windsurf, be aware no patch is available yet.
-
Audit repositories before opening them with AI tools. Run
find . -type lto check for symlinks in cloned repos before instructing an agent to process them. -
Review your approval history. In Claude Code, check
.claude/settings.local.jsonfor overly broad permission rules. In Codex, review~/.codex/rules/default.rules. A single tricked "always allow" creates a persistent bypass. -
Treat AI agent sessions as privileged processes. They run with your credentials, your SSH keys, your shell environment, and your filesystem access. The blast radius of a compromised agent session is the blast radius of your user account.
-
Consider external monitoring. The approval prompt is not sufficient as a sole security control. Independent filesystem monitoring (inotify-level observation of what files actually change), network interception (what requests actually leave the machine), and approval auditing (structured records of what was approved and whether the action matched) provide defense in depth that no internal prompt can subvert.
GhostApproval is probably not a one-off. As agents get more filesystem and network authority, this pattern will show up in new forms. Today it is SSH keys. Tomorrow it is CI config, infrastructure code, or a production branch. Build the outer layer before the next variant ships, not after.