GhostApproval: The Approval Dialog That Doesn't Know What It's Approving
A developer opens a repo. The AI coding assistant is asked to "set up the workspace." It reads a README that says: add a line to project_settings.json. Up pops the approval dialog: "Make this edit to project_settings.json?" The developer clicks yes. The file that gets written is ~/.ssh/authorized_keys, and the line added is the attacker's SSH key.
That is GhostApproval, disclosed by Wiz Research and covered by The Hacker News, The Register, and Infosecurity Magazine. It affects six of the most widely used AI coding assistants: Amazon Q Developer, Anthropic Claude Code, Augment, Cursor, Google Antigravity, and Windsurf.
The trick underneath is symlink-following — CWE-61, on the books since Unix had home directories. What is new is where it lands.
The chain, in three moves
A malicious repository ships two things: a symlink named project_settings.json that resolves to ~/.ssh/authorized_keys, and a README telling the assistant to append the attacker's SSH public key to project_settings.json. From Wiz's PoC:
- The developer asks the assistant to set up the workspace.
- The assistant reads the README, resolves the write path, and calls the tool that edits files. In several tools, the assistant's internal reasoning explicitly noted the resolved target. In one recorded example, the model wrote: "I can see that project_settings.json is actually a zsh configuration file."
- The approval dialog does not carry that knowledge forward. It shows
project_settings.json. The developer clicks yes. The line goes intoauthorized_keys. Passwordless remote access is granted.
What the boundary was supposed to be
Every one of the six tools shipped an approval prompt as the "human in the loop" — the moment a human, not the agent, decides whether the write happens.
GhostApproval is not a bypass. The prompt fired. The developer approved. What the prompt described and what the write did were two different things. Wiz's term — informed-consent bypass — is the right one. The human cannot consent to a file operation whose real target is hidden behind the string the UI showed.
Different from GuardFall (safety filter checked a text form of the command that Bash rewrites before running) and DuneSlide (agent's own sandbox helper rewritten out from under it). Same class: a control that reads well on paper misdescribes what the OS is about to do.
Vendor responses, in three shapes
- AWS, Cursor, Google treated it as in-scope, rated it high or critical, patched, and assigned CVEs. Per Wiz, AWS shipped language server 1.69.0 on May 27, 2026, with CVE-2026-12958.
- Anthropic initially rejected the report on the grounds that user-trusted directories plus user-approved prompts place responsibility on the user. Claude Code v2.1.32 resolves symlinks and warns on writes to sensitive files — Anthropic says this hardening shipped in February, nine days before Wiz submitted. The fix is in the product; the disclosure position is that "trusted folder plus approval" is still where the vendor draws the line.
- Augment and Windsurf acknowledged but had not shipped fixes at public disclosure.
If "trusted folder + approval prompt" holds as the boundary, GhostApproval is the user's problem for opening the repo. If it doesn't, the approval prompt has to be structurally accurate about what will be written. Same gap TrustFall named earlier this year, where accepting a folder-trust prompt auto-started every MCP server defined inside, defaulted to yes.
What the pattern actually is
Group recent AI-coding-agent findings by shape and the same trust-mismatch keeps appearing:
- GuardFall — Adversa AI, June 30. Filter reads a command as text; Bash rewrites it before executing; filter sees
r''m, Bash runsrm. Ten of eleven open-source agents affected. - DuneSlide — Cato AI Labs. Prompt injection reaches a file-write path that overwrites Cursor's sandbox helper. The helper the sandbox trusts is no longer the helper it thinks it is.
- GhostApproval — Wiz Research. Approval dialog names a file; the OS write follows a symlink elsewhere. The consent is real; the target is fake.
In every case, an on-paper control describes one thing and the OS does another. Not a model-safety problem. Boundary-honesty: the string presented to the human, and the check the guard performs, has to match the syscall about to happen.
Where the defense actually lives
The industry has spent a year layering static controls — filters that read commands, prompts that ask for consent, config keys that mark folders trusted. GhostApproval sits underneath all of them. Every filter fired. Every consent was granted. The write still landed where it shouldn't have.
The layer that catches this is behavior at the OS boundary, from outside the agent. The signal is not "did the developer click yes." The signal is: the tool call resolved to ~/.ssh/authorized_keys, the sequence "read a repo README, then write into a home-directory SSH file" has no benign explanation for a workspace-setup task, and the write should be stopped at the syscall, not at the prompt.
Sources
- Wiz Research — GhostApproval: A Trust Boundary Gap in AI Coding Assistants
- The Hacker News — GhostApproval Symlink Flaws Could Let Malicious Repos Run Code in AI Coding Agents
- The Register — Bug in top AI coding agents shows that Unix-era security headaches never really die
- Infosecurity Magazine — GhostApproval Flaw Hits Six Major AI Coding Assistants
- DevOps.com — GhostApproval Flaw Featuring Decades-Old Feature Found in Six AI Coding Tools
- The Hacker News — GuardFall Exposes Open-Source AI Coding Agents to Decades-Old Shell Injection Risks
- The Hacker News — Critical Cursor Flaws Could Let Prompt Injection Escape Sandbox and Run Commands
- Help Net Security — TrustFall AI coding CLI vulnerability research
SPR{K3 is a security research operation that pairs offensive vulnerability research with runtime behavioral defense. Defend is our runtime agent. To talk about a deployment, reach us at support@sprk3.com.