GhostApproval: Symlink Flaw Lets Attackers Hijack AI Agent Approvals

Wiz Research's GhostApproval attack uses symlinks in cloned repositories to trick six AI coding agents into writing attacker SSH keys behind a fake approval dialog.
Table of Contents
    Add a header to begin generating the table of contents

    Wiz Research has disclosed GhostApproval, a symlink-based attack that exploits a trust boundary gap in six major AI coding agents — Amazon Q Developer, Anthropic Claude Code, Augment, Cursor, Google Antigravity, and Windsurf — to write attacker-controlled content to sensitive system files while the developer’s approval dialog names only a harmless-looking apparent filename. The attack requires no code execution, no browser exploit, and no MCP vulnerability; a legitimately-formatted repository containing a single symlink is sufficient to trigger it.

    How GhostApproval’s Symlink Technique Defeats AI Coding Agent Approval Dialogs

    The attack begins when a developer clones an attacker-controlled repository that contains a file named project_settings.json. That file is not a JSON configuration file — it is a Unix symlink pointing to a sensitive target on the developer’s machine, such as ~/.ssh/authorized_keys or a shell startup file. The repository’s README instructs the AI coding agent to add a line to project_settings.json as a routine configuration step. The agent follows the instruction, writes the attacker’s SSH public key, and the write goes to the symlink’s real target: the developer’s authorized_keys file. The attacker now has persistent SSH access to the developer’s machine.

    What Claude Code’s Internal Reasoning Identified vs. What the Approval Dialog Displayed

    The critical flaw Wiz documented in its testing with Claude Code was the disconnect between the agent’s internal reasoning and the information presented to the developer for approval. During testing, Claude Code’s own reasoning correctly identified that project_settings.json “was actually a zsh configuration file” — the agent understood the symlink target. The approval dialog shown to the developer, however, named only the apparent file: project_settings.json. The developer saw and approved a write to what appeared to be a local project configuration file while the actual write destination was a sensitive system file entirely outside the project directory.

    Wiz calls this an “informed-consent bypass” — the human remained in the approval loop, but the loop presented false information. The developer approved the operation based on a filename that did not describe what the write would actually modify.

    Why GhostApproval Works Without Code Execution and Through a Legitimately-Formatted Repository

    The attack surface is broader than typical repository-based attacks because GhostApproval does not require the repository to contain any executable code. No malicious script, no exploit payload, no dependency confusion — only a symlink and a README instruction. Any repository a developer clones and hands to an AI coding agent to configure or set up is a potential delivery vehicle. The attacker does not need access to the developer’s machine, does not need to intercept the developer’s network traffic, and does not need to compromise a software package or dependency. Publishing or sharing a repository containing a symlink is sufficient to target any developer who uses an affected AI coding agent to work with that repository.

    Which AI Coding Agents Are Affected and Where Patches Stand Following Wiz’s Disclosure

    Wiz disclosed GhostApproval to the six affected vendors before publication. Three vendors shipped fixes following the disclosure; two had not patched by publication date. Anthropic disputed Wiz’s classification of GhostApproval as a security vulnerability, characterizing symlink resolution as expected filesystem behavior for AI coding agents that operate within the developer’s own filesystem context. Anthropic’s position is that an agent operating on behalf of a developer within that developer’s filesystem is not crossing a trust boundary when it follows a symlink — the filesystem context is the developer’s own.

    Why Wiz’s “Informed-Consent Bypass” Framing Distinguishes GhostApproval From Normal Symlink Behavior

    The vendor disagreement centers on a meaningful distinction. Symlinks are a legitimate operating system feature, and an AI coding agent that resolves symlinks while reading files is behaving correctly at the filesystem level. Wiz’s objection is not to symlink resolution itself but to the approval dialog’s failure to surface the resolved target to the developer before confirming the write. An agent that correctly identifies a symlink target internally — as Claude Code did in Wiz’s testing — but then presents only the apparent filename in the approval dialog is exposing the developer to a consent failure: the developer cannot make an informed decision about a write operation when the approval dialog names a different file than the one that will be modified.

    What Developers Cloning Repositories With AI Coding Agents Should Do Now

    Developers who use any of the six named AI coding agents to work with cloned repositories — particularly public repositories or repositories from unfamiliar sources — should verify that symlinks in the repository do not point to sensitive locations outside the project directory before directing an AI agent to modify files. The three vendors who shipped patches following Wiz’s disclosure have updated their agents to resolve and display the symlink target in the approval dialog. Developers using agents that have not patched should inspect repository contents for symlinks before asking the agent to write to any file the repository names in its setup or configuration instructions.

    Related Posts