On July 8, 2026, the security firm Wiz published research on a flaw they named GhostApproval. It is not one bug in one tool. It is the same design mistake, made independently, in six different AI coding agents: Amazon Q Developer, Claude Code, Cursor, Augment, Google Antigravity, and Windsurf (Wiz Research, The Hacker News).

The trick behind it is over 40 years old. It is called a symlink. Once you understand what a symlink is, the whole story makes sense — and so does why fixing it is harder than it sounds.

A symbolic link, or symlink, is a small file that does not hold any real content. It holds a path — an address pointing to another file, somewhere else on disk.

When a program opens a symlink, the operating system does not stop there. It follows the pointer and opens the real target instead. Your code editor does this too. Open a symlink, and you see the content of the file it points to, not an empty pointer file.

This is normal and useful. Symlinks let you keep one real file and reference it from many places, without copying it. Unix systems have used them since the 1980s.

The problem starts when the target of a symlink is something you never wanted to touch.

The trick: a fake config file

Imagine you clone a repository from GitHub. Inside it, you see a file called config.json. You ask your AI coding agent to “set up the workspace” or follow the setup instructions in the README.

But config.json is not really a file. It is a symlink:

ln -s ~/.ssh/authorized_keys ./config.json

This command creates a file named config.json in the current folder. But it does not store any config data. It points straight at ~/.ssh/authorized_keys — the file that controls which SSH keys can log into your machine without a password.

Run that command yourself and you will see the trick immediately. A real attacker does it differently: Git can store a symlink as a regular tracked file, so the attacker commits one into the repository with a relative path like ../../../.ssh/authorized_keys. They do not need to know your username or where your home folder is. The link resolves on your machine, after you clone.

The README asks the agent to “update config.json with the new settings.” The agent does exactly that. It writes to the file named config.json. Because of the symlink, the write actually lands in ~/.ssh/authorized_keys.

What happens next depends on what the agent writes. If the README tells it to add a specific line — and that line is an attacker’s SSH public key — the attacker can now log into your machine. If the agent just writes ordinary JSON, the result is different but still bad: your authorized_keys file is corrupted, and your own keys stop working.

That distinction matters. The symlink does not grant access by itself. It redirects the write. Whether that becomes a break-in or a broken machine depends on the content the attacker convinced the agent to write. Both outcomes come from the same root problem: the agent wrote somewhere it was never supposed to reach.

Why the approval prompt didn’t save you

Most AI coding agents run inside some kind of sandbox. Before writing a file outside the project folder, they are supposed to show you a prompt: here is the file, here is the change, click Accept or Reject.

That prompt is your last line of defense. Wiz found that, in most of the six agents tested, the prompt showed the symlink’s nameconfig.json — not the real file it pointed to. You see a harmless filename. You click Accept. The agent then follows the pointer and writes to the actual target.

You are still “in the loop.” The loop is just showing you the wrong thing.

The failures were not identical across all six tools:

  • Cursor and Google Antigravity showed a confirmation dialog, but it displayed the symlink’s apparent path, not the resolved target.
  • Amazon Q Developer’s agent noted in its own reasoning that the target was a symlink, and wrote to it anyway, before the user saw any prompt.
  • Windsurf was the most severe case: it wrote the file to disk before showing an Accept or Reject button. Rejecting did not prevent the write — it only tried to undo something that had already happened.
  • Augment showed no prompt at all. It read and wrote outside the project silently.
  • Claude Code does show a one-time “do you trust this folder?” prompt when you first open a project. Anthropic points to that as the real consent step (more on this below).

Why six vendors made the same mistake

This is the part that matters most. GhostApproval did not happen because six teams copied the same buggy code. It happened because they all built the same design.

Almost every one of these agents follows the same rule: check if a file path is inside the project folder before writing outside it, then ask permission if it isn’t. The mistake is checking the name you were given, not the place that name actually points to — a symlink was never resolved to its real path (a step called canonicalization) before the check or the approval prompt ran.

Different teams, different codebases, different companies — and they converged on the identical gap. That is what makes GhostApproval a design-level problem, not a typo one team happened to make.

How the six vendors responded

Three vendors shipped fixes fast:

  • AWS patched the Amazon Q Developer language server in version 1.69.0 (AWS security bulletin, tracked as CVE-2026-12958).
  • Cursor shipped a fix in version 3.0.
  • Google patched Antigravity.

Augment and Windsurf acknowledged the report, but neither had shipped a fix at the time Wiz published.

Anthropic disputes that this is a bug at all. Their stated position is that the scenario sits outside their threat model: when you start Claude Code in a folder, you already confirm that you trust it. Combined with the write-approval prompt, they argue, the user has consented twice.

Security researchers disagree with that framing. Trusting a folder is not the same as consenting to a prompt that shows you the wrong filename. Both sides have a point — and that disagreement is itself the real story. Nobody has settled on what an AI agent’s sandbox is actually supposed to guarantee.

GhostApproval was not the only sandbox story in Cursor that season. A separate flaw, called DuneSlide, worked through a completely different mechanism: prompt injection instead of a fake file.

Researchers at Cato Networks found that hidden instructions — planted in a web page or an MCP server response that the agent reads on your behalf — could steer Cursor’s terminal tool into targeting a folder outside the project, then overwrite the sandbox’s own enforcement binary. Once that binary is overwritten, every following command runs unsandboxed (The Hacker News, Cato Networks).

DuneSlide was tracked as CVE-2026-50548 and CVE-2026-50549, scored 9.8 out of 10 on the CVSS scale — close to the maximum possible severity. Cursor patched it in version 3.0, the same release that fixed its GhostApproval issue.

Two unrelated bugs, two different mechanisms, one shared lesson: sandboxing a tool that reads untrusted text and writes to a real filesystem is much harder than “check the path and ask permission.”

What you should actually do today

  1. Don’t treat a cloned repository as a safe neighborhood. Any file inside it — including one that looks like plain JSON — can be a symlink pointing somewhere else.
  2. Read approval prompts as unverified, not as ground truth, until your agent’s vendor confirms it resolves symlinks to their real target before showing you a diff.
  3. Run agents inside a real OS-level sandbox — a container or a restricted user account — instead of relying only on the tool’s built-in approval step. That limits the damage even if a prompt shows you the wrong file.
  4. Keep your tools updated. If you use Amazon Q Developer, Cursor, or Google Antigravity, make sure you are on the patched version.

None of this means you should stop using AI coding agents. It means treating the “Approve” button the way you treat a permission popup on your phone: useful, but not proof that nothing else is happening.