Injection, secrets, access control, supply chains, and the new attacks that target the agent itself.
Ask an agent for a login page and you get a login page. It signs people in, its tests pass, and the demo goes well. Whether a stranger can read someone else's invoice by changing a number in the address is a different question, and nobody asked it. Tests check what the code should do. An attacker looks for what else it will do.
So the first part of this chapter gives you the classic attacks by name, because a name is something you can demand. "Make it secure" gets you a comment. "Use a parameterised query and add a test that passes ' OR '1'='1 as the name" gets you a fix and the proof of it. You don't need to become a security engineer for that. You need to recognise each attack and know what the real fix is called.
The second part is newer. An agent reads files, web pages and emails, and it can't reliably tell an instruction from the thing it's reading. So the agent is now something to attack: hidden text can give it orders, a tool's description can lie to it, and a package it imagined can be registered by someone who noticed. Nobody has a reliable cure, so you limit what it can do once it's fooled.
In our own experiment (one small model, one-function tasks, 15 runs per cell, no real repo) we went back to the recorded comment renderers with one attack the hidden scenarios never tried. With a vague brief, 7 of 29 produced a javascript: link, and all 7 had passed every hidden scenario. The full harness didn't reduce it. With the right words in the brief, 0 of 29. The string as we recorded it doesn't run: these programs cut a link at its first closing bracket, leaving alert(1, which is a syntax error. An attack string with no brackets produced the link in the same 7 and ran when clicked in Chromium, so the hole is real. That is a small, limited result, and it is this chapter's argument in miniature. Every attack on this page runs in your browser against made-up data, and none of them can reach a real system.