
Coding Agents as a Target
Week three has been about the agent layer in general. Today we zoom in on the single highest value target class in the whole series: coding agents. IDE assistants, autonomous dev tools, CI bots, review agents. They are worth their own day because they combine the worst version of all three trifecta conditions, they run where the crown jewels live, and they read untrusted input constantly as a core part of the job.
If you internalize one target profile from this series, make it this one, because it is where agent security failures turn into full developer machine and source code compromise.
Why coding agents are the sharpest trifecta
Walk the three conditions and watch each one hit its worst case.
Condition A, valuable access, maxed out. A coding agent reaches source code, which is the product. It reaches secrets in env files, config, and the developer’s shell environment. It reaches the ability to execute code, which is not data theft, it is control of the machine. And through git and CI it reaches the deployment pipeline. There is almost nothing more valuable on a developer’s machine that the agent cannot touch.
Condition B, untrusted input, constant and structural. This is the part people underrate. A coding agent reads untrusted text all day as its literal purpose: dependency READMEs and source, code it is asked to review from a branch or a PR, issues and tickets describing bugs, documentation fetched from the web, error output from tools and builds, and all the metadata from Day 15, commit messages, branch names, file names. The agent cannot do its job without reading content an outsider wrote.
Condition C, outbound, trivially available. The terminal is the exit. A coding agent that can run commands can curl, can git push, can make a DNS lookup, can write a file somewhere readable. You do not have to find an exfil channel. You hand the agent one when you give it a shell.
So a coding agent is a maximal A, a structural B, and a free C. That is why it is the sharpest target in the series. Every other agent is a weaker version of this.
The execution multiplier
For most agents, a landed injection gets you data. For a coding agent, it often gets you execution, which is categorically worse.
Recall CVE-2026-22708 against Cursor from Day 11: an attacker poisons the execution environment so allowlisted commands like git branch deliver arbitrary payloads, and the allowlist auto approves the very commands needed. And the related finding where an indirect prompt injection caused the agent to write a malicious .cursor/mcp.json without user approval, achieving remote code execution through that config. In both, the outcome is code running on the developer machine, not a record leaked.
Once you can run code on a dev box you have the developer’s git credentials, their cloud keys, their SSH access, their ability to push to main, and often a path into CI and from there into production. The blast radius of a coding agent compromise is the developer’s entire reach, which in many orgs is enormous.
The attack surfaces, specifically
Map the Day 15 vectors onto a coding agent and the nasty ones become concrete.
The repository itself. Source files, comments, docstrings, all readable, and on a public or shared repo, attacker writable. A comment in a file the agent is asked to refactor is in context the moment it reads the file.
Pull requests and issues. The canonical case. The GitHub MCP incident from Day 1 lived here: a booby trapped public issue drove the agent into private repos and out through a PR, because the server token carried blanket access. An external contributor opening a PR or filing an issue is handing the agent attacker text through a channel the workflow requires.
Git metadata. Commit messages, branch names, tags, PR titles. All attacker writable, all read by the agent constantly, all easy to forget as input.
Dependencies. A README, a post install script, a package description pulled during install. This is where the supply chain meets the coding agent, and it connects to the LiteLLM backdoor from Day 1: a poisoned package reaching tens of thousands of installs in hours. The agent reading or running dependency content is reading attacker content.
The build and tool output. Compiler errors, test output, linter messages, all of which can echo attacker controlled strings from the code back into context, the error message vector from Day 15 in its native habitat.
Project config the agent trusts. Files like editor and agent config, which if the agent can be made to write them, become persistence and privilege, exactly the .cursor/mcp.json case.
Lab exercise: the coding agent variant
You can extend your lab to this shape without pointing at anything real. Build a minimal coding agent profile and attack it locally.
- Give your Day 7 agent host three tools: read file, list directory, and run command restricted to a sandbox directory. This is a toy coding agent.
- Create a local git repo in that sandbox with a planted payload in a place the agent reads but a human skims: a comment in a source file, a commit message, or a README.
- Ask the agent to do a normal task, review this file, summarize recent commits, check the project. Watch whether the planted text in the code or metadata gets treated as an instruction.
- Observe the execution multiplier: if the run command tool is reachable, see whether a landed injection can get from reading a comment to running a command in your sandbox.
- Keep the command tool strictly sandboxed, a temp directory, no network, no real credentials. The point is to see the read to execute path, not to run anything dangerous.
This reproduces the core of the real incidents, read untrusted repo content, land an instruction, reach the terminal, in a box you own.
Why coding agents resist the usual mitigations
Two of the standard defenses are especially weak here, worth calling out.
Human approval collapses fastest. A coding agent proposes many actions per task, dozens of file edits, commands, and reads. The developer approving them is in flow, moving fast, and trained by volume to click yes. Approval fatigue, named on Day 2, is at its worst in the IDE because the whole value proposition is speed. The control erodes exactly where it is needed most.
You cannot stop it reading untrusted code. Reading the PR, the dependency, the issue is the job. Condition B is not removable for a coding agent without removing the agent. So the entire defense budget has to go to A and C.
Detection and defense, the honest version
Ordered by effectiveness, tuned for this target.
Sandbox execution hard. The single most important control. The agent’s command execution should run in an isolated environment with no access to real credentials, no network by default, and no reach outside the project. If execution is contained, the execution multiplier is defused, and a landed injection that reaches the terminal reaches a box with nothing on it. This is the coding agent version of constrain the consequence.
Scope credentials and tokens tightly. Day 11, applied to dev. The agent should not hold the developer’s full git and cloud credentials ambiently. Per task, least privilege, short lived. So a compromise does not inherit the developer’s entire reach.
Isolate untrusted code review from privileged action. When the agent processes an external PR or issue, it should be in a mode that cannot push, cannot touch secrets, cannot write config. The dual LLM and information flow patterns from week four are the structural form of this, process untrusted input without privilege.
Treat agent and editor config as protected. Files that control what servers load or what the agent trusts should not be agent writable without explicit, out of band human action, to kill the .cursor/mcp.json class of persistence.
Watch egress from the dev environment. New outbound destinations, unexpected git pushes, surprise DNS, all the Day 9 and 13 egress signals, pointed at the dev box. A coding agent exfiltrating looks like new network behavior.
Pin and review dependencies and MCP servers. The supply chain lessons from Days 9 and 13 land directly, because the coding agent consumes packages and servers as a core activity.
The through line holds once more, and hardest here. You cannot stop a coding agent from reading hostile code, and you cannot rely on a developer to catch every proposed action. So you win by containing execution and scoping credentials, so the inevitable landed injection reaches a sandbox with nothing in it and no way out.
Homework for Day 17
- Build the toy coding agent, three tools, sandboxed command execution, and a local repo with a planted payload in a comment, a commit message, and a README.
- Run a benign task and confirm whether the planted text in code or metadata gets obeyed. Record which location worked best.
- Demonstrate the execution multiplier in your sandbox: show a path from reading a comment to running a sandboxed command.
- Apply the top control: tighten the sandbox, remove network and credentials, and show the same landed injection now reaches nothing.
- Audit a real coding agent you use. List what credentials it holds, whether its execution is sandboxed, and whether it can write its own config. Note the single change that would most reduce its blast radius.
Point 5 is the one with immediate payoff beyond the lab. Most developers have never checked what their IDE agent can actually reach, and the answer is usually everything they can.
Day 18 reproduces a real coding agent CVE in detail, the Cursor allowlist bypass, walking the exact mechanism from injection to arbitrary execution so you understand the class from the inside.