Black Hat Asia 2026 (Singapore, Apr 23–24) — Briefings Deep Dives

Bad Vibes: Pwning Coding Agents 70 Times With The Same Bugs

Talk 29 · AI coding agent security · analysis from the speaker's published deck

Sep 24, 2026 · conferences · 10 min read · 1997 words advanced

Bad vibes — the same three bugs, in nearly every AI coding agent.

conferences blackhat ai-security prompt-injection sandboxing devtools

Official recording, Black Hat YouTube channel · open on YouTube ↗

Nil Ashkenazi and Philip Tsukerman (Palo Alto Networks, formerly CyberArk Labs) spent months testing the guardrails built into today's AI coding agents, Claude Code, Cursor, OpenAI Codex, Gemini CLI, GitHub Copilot, and more, and found the same three bug classes repeating across nearly every one of them: command-injection past an allowlist, filesystem writes that escape the intended workspace, and sandbox escapes that let a supposedly-contained agent touch the host. Across the study: 81+ reports, 18 CVEs (several still reserved), around $50,000 in bounties, and a blunt conclusion, if your favourite coding agent doesn't have many CVEs, that's probably not because it's more secure. All findings were disclosed and most were fixed; I describe the bug categories, not working bypass strings.

Post 29 of my Black Hat Asia 2026 series. This talk is squarely about the security of the tools many of us now use daily to write code, so I've kept the framing practical: what breaks, why the same mistake keeps recurring, and what to actually do about it, without republishing the researchers' exact bypass payloads.

1. Why coding agents need new threat modelling

A classic IDE runs whatever commands you type. An agentic coding tool runs commands an LLM decides to run, often in response to instructions that can originate from outside the developer entirely, a malicious code comment, a poisoned dependency's README, a crafted issue or pull request the agent is asked to review. The researchers frame this as a kill chain: the attacker needs model access (getting the agent to process attacker-controlled content, i.e. a form of prompt injection), then needs to bypass whatever guardrails the tool has in place, to achieve real impact on the developer's machine. Guardrails are therefore not a nice-to-have; for these products they are the entire line of defence once step one (prompt injection) is assumed to be possible, which the researchers treat as a given rather than something to prevent.

2. Command injection: parsing shell syntax is hard

Coding agents need to run real commands, code navigation tools, builds, test suites, so most ship with a terminal tool gated by an allowlist: simple, known-safe commands are auto-approved; anything else asks the user. The security of that gate depends entirely on correctly parsing what a command actually does, including compound commands (chaining, piping, subshells) that can smuggle a disallowed command inside an allowed-looking one.

The researchers found that across product after product, the parsing logic used for the allowlist check was less complete than the shell actually executing the command. A checker built to recognise simple chaining operators would miss command substitution syntax; a checker updated to catch substitution would miss language-specific tricks in more expressive shells (PowerShell being a particularly rich source of this, since it is really a full scripting language wearing a shell's clothes, so plenty of code-execution paths don't look like "commands" to a naive parser at all).

The Gemini CLI case study is illustrative of the whole pattern. An early version simply prefix-matched the command string, so anything chained after an allowed command slipped through. The fix moved to properly parsing the command into its syntax tree and checking every command node, a real improvement. But the underlying shell being parsed (PowerShell) supports executing code through constructs that don't register as a distinct "command node" in that syntax tree at all, so even a technically correct parse of "commands" could still miss code execution hiding in what looks like a plain expression. This is the general shape of nearly every bug in this section: the enforcement logic models a simpler version of the shell than the shell actually is.

Findings here were the largest single category: 26 reports across 16 products, 7 CVEs (several more reserved but not yet public), spanning Claude Code, Codex, Cursor, Gemini CLI, Kiro, VS Code Copilot, and a long list of other agents.

3. Filesystem access: writing outside the sandbox you meant to stay in

An agent must be able to edit files in your project to be useful, but writing outside the intended scope is a direct path to code execution: overwriting a shell startup file, a system-wide autostart location, or the agent's own configuration (which frequently includes settings that themselves specify commands to run, or permission rules that specify what's auto-approved, making config files a doubly attractive target). A well-designed agent should refuse to touch such paths regardless of how the request is phrased.

Two broad failure patterns turned up repeatedly:

  • Path-equivalence gaps. A sensitive-path check written as a simple string match (comparing a path's ending, or comparing it directly) misses the many different ways an operating system lets the same file be addressed: differing letter case where the filesystem treats it as equivalent, alternate short-form or alternate-stream naming conventions on Windows/NTFS, and so on. If the check doesn't normalise a path the same way the underlying filesystem does, an attacker-controlled path that means the same protected file can slip past a check written for only the "obvious" spelling of it.
  • Indirect bypasses via allowed tools. Restricting the agent's edit tool from touching a protected file doesn't automatically restrict every other filesystem-adjacent tool it has, move, copy, or general text-processing utilities the agent is otherwise allowed to run inside the workspace. If those tools are unrestricted, they become an alternate route to the exact same protected destination the edit tool correctly refused.

43 reports across 15 products, 9 CVEs. Notably every major vendor tested had at least some finding in this category, including tools that had already invested visibly in security (Cursor alone had 8 reports, 3 CVEs).

4. Sandbox escapes: when the cage has a door in it

The more security-conscious agents run their command-execution tool inside an actual OS-level sandbox (Linux namespace isolation, or macOS's Seatbelt policy engine), restricting what the sandboxed process can read, write or reach on the host, even if the model is fully compromised by a prompt injection. This is the right idea: assume the model can be made to do anything within its sandbox, and make sure "anything within its sandbox" is not very much.

The escapes found fell into two conceptual categories, both about the gap between a security policy written in terms of file paths and the actual filesystem operations an OS allows:

  • Achieving a protected outcome through an unprotected operation. A policy might correctly deny writing new content directly into a protected path, while still permitting some other filesystem operation, such as moving or renaming an already-permitted file into that location, that produces the exact same end state. If the policy is expressed in terms of "which write calls are blocked" rather than "what can end up at this path by any means," a semantically equivalent but differently-named operation can achieve the same result.
  • Trusting a resolved path more than the resolution process itself. Several sandboxes build their permitted-path rules dynamically, resolving symbolic links and relative references to their real, absolute target before deciding what to allow. That's sound in principle, but it depends on the resolution happening safely and on nothing changing between when a path is checked and when it's actually used, a classic time-of-check/time-of-use gap. Where the agent's own tooling allowed creating filesystem links as an otherwise-unrestricted operation, and separately followed links when reading or writing files, the combination of "you can point a name anywhere" plus "the policy trusts wherever that name currently points" turned into a way to redirect supposedly-scoped operations well outside the intended workspace, in some cases as far as the root of the filesystem.

13 reports, 1 CVE across Claude Code, Codex, Cursor, Gemini CLI and Google Antigravity, smaller in count than the other categories but arguably the most serious, since a sandbox escape defeats the very control that was supposed to make prompt injection survivable.

5. What vendors actually did

CategoryReportsCVEs (incl. reserved)
Command injection267
Filesystem access439
Sandbox escapes131
Total81+18

The researchers' read on vendor behaviour is nuanced rather than uniformly damning: most major vendors fixed reported bugs quickly, but were notably slower to formally assign CVEs, and not every vendor agreed that "an attacker can pop a calculator via prompt injection" constitutes a severe issue worth a CVE at all, a framing disagreement that matters because it affects whether downstream users ever learn a fix shipped. Total bounty payouts across Anthropic, Google, OpenAI and Cursor were around $50,000. The clearest split observed was between vendors visibly investing in both security and agent autonomy simultaneously, versus vendors that, implicitly or explicitly, ask users to pick one or the other.

6. What this means if you use a coding agent

  • Assume prompt injection is possible any time the agent reads content you don't fully control: dependency READMEs, issue text, PR descriptions, scraped documentation, search results. Don't rely on the model "just not doing" something dangerous.
  • Run the agent inside a real, OS-level sandbox or disposable VM/container, not just the agent's own built-in allowlist. The research shows allowlists alone repeatedly fail to model the full expressive power of the shell they're guarding.
  • Treat the agent's own config and permission files as high-value targets, since they frequently control what commands get auto-approved next time; a write there can compound into much more than a single bad command.
  • Prefer agents whose sandbox policy is expressed in terms of outcomes (what can end up where) rather than only which specific tool calls are blocked, and that resolve paths safely and consistently before enforcing rules on them.
  • Keep the agent's filesystem scope as narrow as the task allows, and don't grant it access to secrets, SSH keys, cloud credentials or other high-value files it doesn't strictly need for the current project.

The researchers' own soundbite is worth repeating verbatim in spirit: every bug class they found was present across numerous independently-built products, which strongly suggests these are not isolated implementation mistakes but a genuinely hard problem inherent to building a guardrail around a system as expressive as a general-purpose shell and filesystem.

Does this mean coding agents are unsafe to use?

It means their built-in guardrails alone are not sufficient defence against a determined attacker who can get attacker-controlled content in front of the model. Running the agent with additional, OS-level isolation (a container or VM) closes most of the gap even when the agent's own checks fail.

Are these bugs specific to one vendor?

No, that's the headline finding: the same three bug classes recurred across essentially every major agentic coding tool tested, including the most widely used ones.

Has this been fixed?

Most vendors fixed reported issues, sometimes quickly; formal CVE assignment lagged behind actual fixes in many cases, and some reserved CVE numbers were not yet public at the time of the talk.

Why is a sandbox escape worse than a command injection?

Command-injection and filesystem bugs are serious on their own, but a properly working sandbox is supposed to be the backstop that limits the damage even if those bugs exist. An escape from the sandbox itself removes that backstop entirely.

Takeaways

  • Three bug classes recurred across nearly every major coding agent: command-injection past allowlists, filesystem writes outside the intended scope, and sandbox escapes.
  • Command-injection bugs consistently came from allowlist logic modelling a simpler shell than the one actually executing commands.
  • Filesystem bugs came from path-equivalence gaps and from restricting one tool while leaving other, functionally equivalent tools unrestricted.
  • Sandbox escapes exploited the gap between a path-based policy and the richer set of filesystem operations that can achieve the same end state, including link-resolution timing issues.
  • Totals: 81+ reports, 18 CVEs, ~$50,000 in bounties. Run agentic coding tools inside real OS-level isolation, don't rely on their own guardrails alone.

References & further reading

← prev: REBIRTHDAY (DNS Birthday) next: AlgoBuster (UDS 0x27) →
© cvam — written in plaintext, served warm