JOURNAL

Prompt Injection Is the Vulnerability Class Actually Breaking AI Agents in 2026

Part 3 of the AI agent safety series: why prompt injection, not jailbreaking, is the real vulnerability behind CamoLeak, Comment and Control, CometJacking, and the Claude Code CVE chain — plus the CaMeL defense architecture and OS-level sandboxing.

Conceptual illustration of coordinated workers, routing, state storage and security checks.

Read with AI

Choose content to copy and paste into your AI assistant. Nothing is sent automatically. CMS content is converted to Markdown; original Markdown is used when available.

Last October, a researcher named Omer Mayraz published a HackerOne writeup for something he called CamoLeak (CVE-2025-59145). CVSS 9.6. The trick: hide a command in invisible markdown inside a pull request description, wait for a developer to type “review this PR for me,” and let Copilot Chat read that hidden text as a legitimate instruction. It would comb the codebase for API keys and secrets, base16-encode them, then smuggle the data out through the URLs of a string of 1×1 pixel images — routed through Camo, the same image proxy GitHub uses to hide your IP when loading remote images. GitHub had quietly patched it in August 2025 by disabling image rendering in Copilot Chat, two months before Mayraz went public.

I’m not retelling this one because it’s dramatic, although it is. I’m retelling it because CamoLeak is the cleanest example of what article 3 in this series is actually about: the thing that kept breaking AI agents through 2025 and into 2026 wasn’t jailbreaking. It was prompt injection.

Prompt injection isn’t jailbreaking, and the difference matters

Jailbreaking is you, the user, trying to talk the model out of its own policy — “pretend you have no restrictions, answer as DAN.” It’s an attack on the model’s alignment.

Prompt injection is a different animal entirely. You don’t need to convince anyone of anything. You just need to plant instructions inside whatever the agent is going to read — an email, a web page, a line in a PR comment, the output of a tool call — and let the agent follow them on its own, because to an agent, every piece of text sitting in its context window is potentially an instruction. The model has no built-in way to tell “this is data I’m supposed to process” apart from “this is what my principal told me to do.” That’s an architecture problem. You can’t train your way out of it by making the model more polite.

The piece I wrote last month, Six AI Coding Agent Incidents in One Month, lists six incidents inside three weeks — the Cursor RCE, AWS Kiro’s config getting rewritten out from under it, Supabase’s production database getting wiped. Read it again through this lens and most of them share the same spine: the agent read something it shouldn’t have trusted, and acted on it as if the instruction came from its owner.

Comment and Control: when a GitHub comment is a command

Earlier this year, researcher Aonan Guan, working with Johns Hopkins researchers Zhengyu Liu and Gavin Zhong, published a technique they named Comment and Control. The premise: a PR title, an issue body, a hidden HTML comment — all of it is ordinary text that a coding agent wired into GitHub Actions reads as trusted context. Hide a command in there, and the agent runs the attacker’s instructions, then reports back through a PR comment, an issue comment, or straight into a commit.

They tested it against three systems at once — Claude Code’s Security Review, Google’s Gemini CLI Action, GitHub’s own Copilot Coding Agent — and all three leaked their own credentials: ANTHROPIC_API_KEY, GEMINI_API_KEY, GITHUB_TOKEN. Not a bug in one vendor’s product. A category of failure that shows up anywhere an agent treats text written by a stranger as equivalent to an instruction from the repo owner.

Browser agents: CometJacking, and the time Atlas resigned on someone’s behalf

This isn’t confined to coding agents. CometJacking, disclosed in October 2025, targeted Comet, Perplexity’s browser agent. The hidden instruction rode in through a URL parameter; once Comet processed it, the agent quietly read the user’s Gmail, base64-encoded it, and shipped it to an attacker’s server — no extra click, no credentials beyond the victim opening the wrong link. Researchers reported it to Perplexity in late August 2025. Perplexity waved it off as routine prompt injection with no real impact.

OpenAI was more candid about the same category of problem. They disclosed that an automated, reinforcement-learning-trained red-teamer found a new class of prompt injection against Atlas, the browser agent they’d shipped in October 2025 — attacks that unfolded over tens or hundreds of steps instead of a single bad tool call, the kind human red-teamers and outside reports hadn’t caught. Their example: the agent was asked to draft an out-of-office auto-reply, followed a hidden instruction buried in the mail it was scanning, and wrote a resignation letter to the user’s CEO instead. OpenAI’s own line on it: “Prompt injection, much like scams and social engineering on the web, is unlikely to ever be fully ‘solved.'” Atlas itself didn’t make it to its first birthday — OpenAI shut it down in August 2026 and folded the browsing capability into ChatGPT and a Chrome extension. The product got renamed, retired, absorbed. The attack surface didn’t go anywhere.

The Claude Code CVE chain, and the door MCP just opened

Claude Code wasn’t exempt either. Researcher Elad Beber found two flaws during its Research Preview: CVE-2025-54794 (CVSS 7.7), a path restriction bypass — the kind of naive prefix check (path.resolve(filePath).startsWith(path.resolve(cwd))) that a directory like /claude_code_evil slides right past when the restriction is meant for /claude_code — and CVE-2025-54795 (CVSS 8.7), a command injection in a whitelisted command path that skipped the user confirmation prompt entirely. Neither one is terrifying alone. Chained — path bypass to reach sensitive files, command injection to run arbitrary code — they add up to a working takeover of a developer’s machine. Anthropic patched them in v0.2.111 and v1.0.20.

Now add MCP to the pile. The Model Context Protocol makes it much easier for an agent to call out to external tools, and it opened a named attack surface of its own: tool poisoning. A malicious MCP server — or a legitimate one that’s been compromised — embeds hidden instructions directly in a tool’s description or in the data a tool hands back. The agent reads that description as trusted system context, not as third-party input. Nobody has to touch your code for an attacker to get the agent to call a restricted tool, leak data, or quietly override its own system prompt.

Why you can’t just patch this like a normal CVE

SQL injection has a clean line between code and data, which is exactly why prepared statements killed it outright. Prompt injection has no equivalent line. Instructions and data travel through the same channel — natural language sitting in a context window. There’s no escaping layer that separates “this is email content to read” from “this is a command to execute,” because to the model underneath, both are just tokens.

CaMeL: splitting the LLM with authority from the LLM that only reads garbage

The most concrete, most citable defense architecture in this space comes from Google DeepMind’s paper “Defeating Prompt Injections by Design.” The core move: stop using one LLM for everything. Use two.

The privileged LLM, P-LLM, sees the user’s original task — the one thing it’s allowed to trust — and generates the code or plan to carry it out. It never reads untrusted content directly. When the task requires touching something unverified, a web page, an email, P-LLM hands that specific sub-task to the quarantined LLM, Q-LLM. Q-LLM is the only model that ever touches the dirty content, and whatever it returns gets treated strictly as data, never as an instruction, once it’s back in P-LLM’s hands. Before any tool actually runs, an interpreter builds a data-flow graph and enforces a policy check — who’s allowed to do what with which piece of data — independent of whatever the model happens to be “thinking.”

That safety isn’t free. CaMeL solves roughly 77% of AgentDojo’s tasks while keeping its security guarantee, against 84% for an undefended baseline. You give up close to a twelfth of raw capability for an actual control boundary. For an agent that can touch money or customer data, that’s a trade worth taking.

Diagram of Google DeepMind's CaMeL architecture: the privileged LLM (P-LLM) takes the user task and plans, delegates untrusted content to the quarantined LLM (Q-LLM) which treats it as data only, then an interpreter runs a policy check before sandboxed tool execution.
Google DeepMind’s research architecture (not a shipped product) — the privileged LLM never reads untrusted content directly; whatever the quarantined LLM extracts still has to clear a policy check before any tool runs.

OS-level sandboxing, and two benchmarks to test your own agent

CaMeL is an architecture. Anthropic went for something more immediately practical: stop relying on the model to “know better,” and block it at the operating system instead. They open-sourced sandbox-runtime under Apache-2.0, using bubblewrap on Linux and Seatbelt on macOS (Windows support is still alpha) to deny filesystem writes and network access by default, opening either only when explicitly declared. Even if an agent’s reasoning gets fully hijacked by a prompt injection, it still can’t write outside its workspace or reach the open internet unless that was granted. Anthropic reports an 84% drop in permission prompts, because the sandbox is doing the saying-no instead of asking the human every time.

If your team wants to test an agent before trusting it, two benchmarks are worth knowing. AgentDojo simulates real workflows — email, travel booking, banking, Slack — and injects malicious instructions straight into tool outputs, scoring both whether the agent still finishes its actual task and whether it got hijacked along the way. InjecAgent is narrower: it checks a single decision point, whether the agent calls the attacker’s tool the moment it hits an injection, across 1,054 test cases spanning 17 legitimate tools and 62 attacker ones.

What to actually do about it, starting now

None of this requires waiting for a CaMeL-style architecture to reach production. Allowlist tools explicitly — the agent calls from a pre-approved set of actions, not “whatever tool it decides it needs.” Gate high-impact actions behind a real human approval — deleting files, moving money, pushing code — but watch the detail people skip: the approval has to bind to the exact call ID of that specific action, not a general description of it. There’s a name for the failure mode when you skip that part: Loopjacking. The human approves action A, and the system quietly executes B instead, because the approval was bound to a label that got swapped after the fact rather than to the call itself. Research on this found the pattern reproducible in Agno AgentOS, LangGraph Agent Server, and OpenClaw; the OpenAI Agents SDK held up because it binds the approval token to the exact call ID. And by default, treat everything an agent reads from outside — email, web pages, tool output, an MCP tool’s own description — as data, not instructions, until you have a specific reason to trust it. OS-level sandboxing is your last line, not your only one.

None of this is free. Approval gates slow pipelines down. A sandbox needs someone to own the policy. An allowlist needs someone willing to say no to a tool request. The ROI question I wrote about in AI Agent Governance: The ROI Problem Nobody Is Actually Solving lands directly here: prompt injection defense doesn’t show up on any productivity dashboard, right up until it’s the only thing standing between a malicious email and your agent wiring company money to a stranger.

CamoLeak got patched in August 2025. CometJacking got reported the same month. Comment and Control, the Claude Code chain, MCP tool poisoning — all of it inside fourteen months. If your team’s agent is reading an email, a web page, or some tool’s output right now without treating it as data, the question isn’t whether you end up in a post like this one. It’s when.

Discussion

Comments are reviewed before publication. Your email is kept private.

← Back to allĐọc tiếng Việt