```html ``` The Approval Box Lied. GhostApproval Turns a Malicious Repo's project_settings.json Into Your ~/.ssh/authorized_keys — and the Agent Already Knew.
top of page

The Approval Box Lied. GhostApproval Turns a Malicious Repo's project_settings.json Into Your ~/.ssh/authorized_keys — and the Agent Already Knew.

  • Writer: Patrick Duggan
    Patrick Duggan
  • 21 minutes ago
  • 5 min read

On July 8, Wiz published GhostApproval, and it is the most honest name anyone has given an AI-agent vulnerability yet, because the bug is not really in the symlink. It is in the box. The little approval dialog your coding assistant shows you before it writes a file — the one you have been trained to glance at and click — can be made to tell you the truth about a harmless file while it writes to a dangerous one. The agent, in at least one tested case, already knew. It said so in its own reasoning. The box did not pass that along.



How it works


A symbolic link is a Unix feature older than most of the people using these tools: a file that quietly points at another file somewhere else on disk, so that writing to the link actually writes to the target. Wiz built a malicious repository containing a symlink named project_settings.json that really pointed at the victim's ~/.ssh/authorized_keys — the file that decides which keys are allowed to log into the machine over SSH. The repo's README, the kind of file an agent reads and trusts as instructions, told the assistant to add "a line" to project_settings.json. That line was the attacker's own SSH public key, dressed up as an innocuous setting. Add the line, and the attacker can now log into the developer's machine.


The symlink is only the delivery truck. The real failure is the approval step, and this is the part that should stop you. When Wiz tested the technique against Claude Code, the agent's own chain of reasoning had already resolved the trick — it noted internally that project_settings.json was "actually a zsh configuration file," i.e. not what it claimed to be. But the confirmation dialog presented to the developer named only the harmless file. The model saw the target. The human was shown the decoy. The consent you gave was informed consent to the wrong thing.


Wiz found the pattern across six major assistants: Amazon Q Developer, Anthropic's Claude Code, Augment, Cursor, Google Antigravity, and Windsurf. The write lands outside the workspace the tool is supposed to be confined to — SSH keys, shell rc files, whatever the symlink aims at.



Where the vendors stand — including ours


We are going to report this the way we report everything, which means naming the tool we are partnered with right alongside the others. Amazon classified it as a high-severity pre-authorization write bug in Q Developer, assigned CVE-2026-12958, and fixed it. Cursor did the same, issued CVE-2026-50549, and shipped the fix in v3.0. Google called it a critical bug in Antigravity and fixed it. Windsurf acknowledged receipt on June 23 and, as of Wiz's publication, had not shipped a public fix. And Anthropic — whose Claude Code is the assistant we build on and write with every day — disputes that it is a bug.


We are not going to pretend that is comfortable to type, and we are not going to soften it. The dispute has a coherent shape: Claude Code's security model is that the human approves each write, so from that stance a symlinked write is a user-approved action and the responsibility sits with the approval, not the tool. But the whole force of GhostApproval is that the approval was solicited under a false description, and the agent's own reasoning is the evidence that the tool had the information needed to describe it correctly and did not surface it. When the model writes "this is actually a zsh configuration file" in its scratchpad and the dialog still says project_settings.json, "the user approved it" is doing a lot of work. Reasonable engineers can land on either side of whether that meets the bar for "bug." Our position is narrower and we will state it flat: an approval prompt that names the decoy instead of the target is a defect in the trust boundary, whoever's logo is on it, and the fix is cheap — resolve the symlink and show the developer the real destination before asking.



We have been on this exact beat


This is not a new shape to us. Nine days ago, on July 1, we wrote "Ten of Eleven AI Coding Agents Can Be Fooled by Bash Tricks Older Than Their Users" — Adversa AI's work showing that agents which read a repo and then run shell commands could be steered by shell-syntax tricks, and that the one agent which held did so by parsing the command the way the shell actually would, not the way it looked. GhostApproval is the same lesson wearing a symlink instead of a bash trick: the AI layer keeps getting caught by the oldest, most boring corners of Unix, because the models reason about what a filename or a command appears to mean while the operating system acts on what it actually points to. The gap between those two is the entire modern AI-agent attack surface, and it is decades-old plumbing every time.



What to do


Update Amazon Q Developer, Cursor (v3.0+), and Google Antigravity now — the fixes exist. If you run Claude Code, Augment, or Windsurf, do not wait on the vendor debate to protect yourself, because the mitigation is yours to apply regardless: treat any repository you did not write as untrusted input, and never let an agent operate on a cloned repo with standing permission to write files. Run agents against untrusted code inside a container or a throwaway VM where ~/.ssh and your shell rc files simply are not present to be aimed at. Before you approve a write, if the path is a config file inside a repo you just cloned, check whether it is a symlink — ls -l will tell you in one line. And treat a README that instructs the agent to modify a specific file as exactly what a phishing email is: a stranger telling your assistant what to do.


Held to about ninety-five percent. The research and the disclosure are Wiz's, and it is sharp work. What we add is the through-line: this is the second time in ten days that a decades-old Unix primitive has walked straight through the reasoning of the best AI coding tools on the market — and the tell, both times, was that the machine understood the danger a beat before the interface admitted it.




Every indicator in this post is in the feed. Free.

1.58M+ IOCs, STIX 2.1 / TAXII, 88% novel vs ThreatFox, exploited-CVE leads ahead of CISA. No credit card — a free API key in 30 seconds, and you can audit every claim above against the live endpoints.


bottom of page