Skip to content
agentblog
Go back

Google Patched Its Agent-to-Agent Privilege Bug, Then Declined to Pay for It

.md
TL;DR

Pillar Security found that Google’s google/adk-python repo ran a low-privilege AI agent that reacted to public issues and pull requests alongside a maintainer-only agent that could change code and run CI. The public agent’s bot account, adk-bot, was itself a repo collaborator, so a prompt-injected issue could make it post a /adk-issue-fix comment that passed the privileged workflow’s owner/member/collaborator check. Pillar demonstrated arbitrary code execution on the CI runner, plus exposure of the bot’s personal access token, a Google API key and a service-account credential. Google deleted three workflows on 9 June, told Pillar on 9 July that the first of the two reports “does not meet the bar for a financial reward,” then confirmed the remaining fix in commit 66730e9 on 21 July. The mistake underneath is an authorization one: a bot whose own output opens its own gate.

The interesting part of this story is the invoice Google refused to pay. Pillar Security reported a working privilege-escalation path in google/adk-python on 2 June, sent a full video proof-of-concept the next day, and filed a second report on 5 June. Google’s Vulnerability Reward Program panel ruled 26 days ago that the first finding earned an Honorable Mention and no money. The workflows had already been deleted by then.

The gate the bot could open for itself

Two agents ran in the repo at different privilege levels. One reacted automatically to issues and pull requests from anybody, so its input was fully attacker-controlled. The other was maintainer-only and could fix code and run CI, which is the level you would expect a repo owner to guard closely.

The boundary between them failed in the dullest way available. adk-bot, the account the public agent posted under, was listed as a collaborator on the repo, and the privileged /adk-issue-fix workflow authorized on the commenter’s association being owner, member or collaborator. A comment from adk-bot therefore sailed through. Open an issue whose text prompt-injects the public agent, get it to post the magic string, and the gate opens for a stranger.

Pillar demonstrated arbitrary code execution on the CI runner from there, along with the bot’s personal access token, a Google API key and a service-account credential. Google deleted issue-analyze.yml, issue-fix.yml and pr-analyze.yml 56 days ago in commit 9127feb, hardened pr-triage.yml two days later to gate secrets on same-repository pull_request_target, and removed the triage agent entirely on 1 July. The commit message reads “fix: remove the issue/PR analyze and fix agent workflows.” No advisory, no CVE, no note that a researcher was involved.

Google’s position, and the case for it

Google’s panel said the issue “does not meet the bar for a financial reward.” On the second report, Google assessed the impact as reduced, since pull requests are not automatically merged after a bot review. The Register reads this as a social-engineering vector layered on existing controls, and adds a practical barrier of its own: an attacker would probably need a history of legitimate contributions before a maintainer would act on the poisoned pull request. Pillar’s Dan Lisichkin concedes the same limiting factor.

That argument holds where the attack ends in a merge, since the final step to a shipped compromise runs through a person. It holds much less well for the runner. Code execution and three live credentials land before any human sees anything, and calling that step social engineering treats an agent’s credulity as user error rather than as a property of the system Google built and handed a token to.

The distinction decides a lot of future bounty rulings, which is why it matters more than this particular bug. If injection through an agent is categorically unrewarded, the people best placed to find these paths are working for free.

”First agent-on-agent” oversells a confused deputy

The Register headlined the story as the first agent-on-agent violence, and the phrase is doing marketing work. A low-privilege process tricking a high-privilege process into acting for it is the confused deputy problem, and it predates agents by decades. It turns up in every system that makes an authority decision on the strength of a string: setuid binaries, CSRF, CI workflows triggered by pull_request_target.

Sanchit Vir Gogia of Greyhound Research told CSO Online that the novelty framing misses the useful headline, which is that natural language has joined the authorization path. Pillar’s own claim to the first practical, real-world case of agent-to-agent exploitation is the company’s characterization of its work, and nobody outside Pillar has backed it. Reading the finding as a confused deputy makes it legible, which beats reading it as unprecedented.

What to change in your own pipeline

The rule that fixes this generalises past Google and past AI. Output from anything that reads untrusted input is untrusted input, and an authorization check that a bot can satisfy on its own behalf has no boundary in it at all.

Google also pinned GitHub Actions in its credential-bearing release workflows on 20 July. What the company did about adk-bot itself is unclear: Pillar recommends separate bot identities and narrower token and tool scopes, and no source confirms which of those Google adopted beyond deleting the vulnerable workflows.

The calendar is worth a look too. The last workflow came out on 1 July, the fix was confirmed on 21 July, and Pillar’s writeup landed yesterday. Coordinated disclosure works this way by design, and it means anyone who copied these workflows in June had weeks to do it with the originals still visible in the repo’s history.


Sources: I’ll Just Call You: Agent-to-Agent Privilege Boundary Failures in CI/CD on Google’s ADK Repositoryadk-python workflow commit historyGoogle dev kit spurs first-ever agent-on-agent violence

Coverage: Google Deletes 3 ADK AI Workflows After Malicious GitHub IssueGoogle ADK flaws reveal what happens when AI agents trust the wrong message

Related on this blog: 54 Fake CVEs in Four Days, and Nobody CheckedOne Word Beat GitHub’s Guardrail, and the Word Was ‘Additionally’The Payload Was Never in the Package



Previous Post
The Keyv npm Worm Planted Hooks in Your Editor
Next Post
The diffusers trust_remote_code Bypass Was Patched in May