Sicherheit

Agent ruft Agent: die Lücke in der CI-Pipeline

Ein öffentlicher Triage-Agent lässt sich per Prompt Injection dazu bringen, einen privilegierten Agenten zu starten. Was der Fall für eure CI bedeutet.

In eurem Repository sitzt ein Agent, der eingehende Pull Requests sichtet. Er darf wenig: kommentieren, Labels setzen, mehr nicht. In derselben Pipeline sitzt ein zweiter Agent, der deutlich mehr darf, aber nur von Maintainern gestartet werden kann. Zwei Agenten, sauber getrennte Rechte. Sieht nach solider Architektur aus.

Genau diese Konstruktion hat Dan Lisichkin von Pillar Security im Repository hinter Googles Agent Development Kit für Python auseinandergenommen. Sein Ergebnis: Der harmlose Agent lässt sich dazu überreden, den mächtigen zu rufen. Pillar nennt es den ersten praktischen Fall von Agent-gegen-Agent-Ausnutzung in einem Produktivsystem, The Register hat den Fall am 03.08.2026 aufgegriffen. Das betroffene Paket google-adk kam in den vergangenen Monaten auf über 90 Millionen Downloads.

Der Fall ist gemeldet, behoben und öffentlich dokumentiert. Interessant ist er nicht wegen des Schadens, sondern wegen des Musters: Es entsteht genau da, wo bisher niemand hingeschaut hat, nämlich zwischen zwei für sich genommen vernünftig gebauten Agenten.

Der Fehler steckt nicht im Agenten, sondern im Konto

Der Auslöser war eine Entscheidung, die im Alltag völlig unspektakulär wirkt. Der Triage-Agent des Repos kommentierte nicht als GitHub-Bot oder als GitHub App, sondern als normaler Nutzer mit einem Personal Access Token. Und dieses Nutzerkonto, adk-bot, war im Repository als Collaborator eingetragen.

Damit war der Agent formal ein privilegierter Mensch. Und die mächtigen Workflows im Repo prüften genau das: Sie ließen sich starten, wenn ein Member, Collaborator oder Autor einen Kommentar schrieb, der mit @gemini-cli beginnt.

Wer die Kette zu Ende denkt, sieht das Problem sofort. Wenn ein Angreifer den Triage-Agenten dazu bringt, einen Kommentar zu schreiben, der mit @gemini-cli beginnt, dann hat er die Zugangskontrolle nicht gebrochen, sondern erfüllt. Der Agent ist ja Collaborator.

Warum sich der Agent überreden ließ

Die erste Injection ignorierte das Modell schlicht. Nicht aus Sicherheitsbewusstsein, sondern weil sein System-Prompt ihm auftrug, sich an die Contribution-Richtlinien des Projekts zu halten. Also formulierte Lisichkin die Anweisung so um, dass sie wie ein Schritt aus genau diesen Richtlinien aussah: ein "Hinweis für die Triage", der erklärt, Änderungen im tools/-Bereich liefen in diesem Repo über einen automatischen Review, und der bittet, dafür einen Kommentar zu hinterlassen, dessen erste Zeile mit @gemini-cli beginnt.

Der Agent tat, was er tun sollte: den Richtlinien folgen. Dass die Richtlinie diesmal vom Angreifer kam, konnte er nicht unterscheiden.

Das ist der Punkt, an dem klassische Sicherheitsintuition nicht mehr trägt. Ein Agent, der fremden Text liest und dabei ein Credential hält, ist nach Lisichkins Formulierung ein Werkzeug zur Rechteausweitung, das Englisch spricht. Es gibt keinen Exploit-Code, den ein Scanner finden könnte. Es gibt nur einen höflich formulierten Absatz in einem Pull Request.

Was daraus wurde: ein Review, den nie ein Mensch gemacht hat

Der interessante Teil ist die Wirkung. Der erbeutete Token konnte weder Code pushen noch Pull Requests mergen, er hatte nur issues: write und pull-requests: write. Klingt nach wenig. Ist es nicht.

Mit diesen Rechten ließ sich Folgendes bauen: Ein Angreifer legt zuerst einen Pull Request an, der einen echten Fix mit Schadcode mischt, etwa einer manipulierten Abhängigkeit. Er wartet, bis ein Mensch diesen PR triagiert. Dann öffnet er einen zweiten Pull Request, in dem die Prompt Injection steckt. Der Agent verarbeitet den zweiten, handelt aber auf dem ersten:

SchrittGenutzte BerechtigungWirkung nach außen
Kommentar des Triagers umschreiben zu "Sieht gut aus, starte den automatischen Check"issues: write erlaubt das Bearbeiten fremder KommentareEin Mensch scheint den Review angefordert zu haben
Fortschrittskommentar als github-actions[bot] postenerbeuteter GITHUB_TOKENDer Bot scheint zu arbeiten
Formales Review-Event mit Zustimmung absetzenpull-requests: write über die GraphQL-APIDer PR trägt eine grüne Freigabe
Review-Anforderung zurückziehen, Label auf "approved" setzenpull-requests: writeDer PR sieht fertig geprüft aus

Am Ende steht ein Pull Request mit einer lückenlosen, plausiblen Historie: Ein Mensch hat einen Review angefordert, der Bot hat geprüft, der Bot hat zugestimmt. Nichts davon ist passiert. Lisichkin beschreibt es als Spur, die vollständig fabriziert ist.

Genau hier setzt auch Googles Bewertung an. Der Konzern hat die Ursache behoben und das Repository gehärtet, eine Prämie aber abgelehnt: Der Angriff erfordere Social Engineering, weil ein Maintainer den PR am Ende immer noch selbst mergen müsse. Das ist sachlich richtig und trotzdem ein schwacher Trost, denn der ganze Zweck der gefälschten Spur ist ja, genau diesen Menschen zum Klick auf "Merge" zu bringen. Die Anerkennung gab es als Credit, nicht als Geld.

Der zweite Fund: Warum eine Befehls-Allowlist nicht reicht

Kurz nach der ersten Meldung baute das Repo eine neue Automatisierung ein, und die brachte einen zweiten, technisch klareren Fund mit. Ein Agent durfte dort Shell-Befehle ausführen, abgesichert durch eine Prüffunktion: Sie verbot Shell-Metazeichen und ließ nur Befehle durch, deren erstes Wort gh oder git ist.

Diese Absicherung hält nicht, und der Grund ist lehrreich für jeden, der Agenten Befehle ausführen lässt. git ist selbst ein Startprogramm für fremden Code:

# beide beginnen mit "git" und enthalten kein einziges verbotene Zeichen
git -c core.hooksPath=<verzeichnis> hook run pre-commit
git -c "alias.x=!<befehl>" x

Dazu kamen zwei weitere Lücken: Die Datei-Schreibwerkzeuge des Agenten wurden gar nicht geprüft, er konnte sich das Skript also erst selbst schreiben und dann über einen der erlaubten git-Tricks starten. Und die erlaubten Programme gh und git liefen ohnehin mit dem langlebigen Token des Bot-Kontos in der Umgebung. Auslösen ließ sich der Ablauf, indem ein beliebiger Fremder ein Issue öffnete.

Die Lehre daraus ist unabhängig vom konkreten Repo: Eine Allowlist auf Befehlsnamen ist keine Sandbox. Sie prüft, wie ein Befehl anfängt, nicht was er tut.

Was das für eure eigenen Setups heißt

Die meisten Teams betreiben keine öffentlichen Repos mit zwei Agentenklassen. Aber die Bausteine dieses Angriffs stecken in ziemlich normalen Setups: ein Bot, der Issues vorsortiert. Ein Agent, der PRs kommentiert. Ein Workflow, der auf ein Stichwort im Kommentar reagiert. Sobald zwei davon zusammenkommen, existiert eine Übergabe, und die ist ab jetzt Teil der Angriffsfläche.

MaßnahmeWarum sie im ADK-Fall geholfen hätte
Agenten eine eigene Identität geben, kein Menschenkonto und kein persönliches TokenDie Rechteprüfung hätte adk-bot nicht als berechtigten Menschen durchgewinkt
Auslöser wählen, die eine Injection nicht erzeugen kannEin Stichwort im Kommentartext ist genau das, was ein überredeter Agent schreiben kann
Agenten mit Zugriff auf fremden Text als potenziell fremdgesteuert behandelnIssues, PRs, Tickets und Support-Chats sind Eingaben von außen, unabhängig davon, wer sie verwaltet
Werkzeuge und Token pro Agent minimal haltenOhne Tool-Scoping hatte der Agent Zugriff auf alles, mit engem Scoping wäre die Kette abgerissen
Menschliche Kontrollen technisch verankernBranch Protection, verifizierte Reviews und Vier-Augen-Prinzip verhindern, dass eine gefälschte Freigabe zum Merge wird

Der letzte Punkt ist der wichtigste, und er ist auch der Grund, warum der Fall glimpflich ausging: Google hatte diese Kontrollen. Die Signale ließen sich fälschen, der Merge nicht.

Einordnung

Dieser Fall gehört in eine Reihe mit anderen Mustern, die wir hier schon beschrieben haben, unterscheidet sich aber in einem Detail. Bei der Clean-Repo-Falle wird ein einzelner Agent auf dem Entwicklerrechner überredet. Bei der MCP-Anbindung wächst die Angriffsfläche mit jedem Werkzeug, das ein Agent bekommt. Hier ist beides erfüllt, und dazu kommt etwas Neues: Der Angriff nutzt aus, dass zwei Agenten einander mehr vertrauen, als sie sollten. Wer den Schritt vom einzelnen Vorfall zum eigenen Betriebsmodell machen will, findet die Leitplanken dafür unter Coding-Agenten im Team sicher betreiben.

Simon Willison hat für die Voraussetzungen den Begriff der tödlichen Dreifaltigkeit geprägt: Ein Agent liest fremden Text, hat Zugriff auf etwas Wertvolles und kann nach außen kommunizieren. Der ADK-Fall zeigt die Variante, in der diese drei Zutaten nicht in einem Agenten zusammenkommen, sondern verteilt über zwei, verbunden durch eine Übergabe, die niemand als Vertrauensgrenze modelliert hatte.

Fazit

Jede einzelne Komponente in diesem Aufbau war verteidigbar. Ein öffentlicher Triage-Agent ist sinnvoll. Ein Review-Agent nur für Maintainer ist sinnvoll. Knapp geschnittene Token sind gute Praxis. Der Angriff lebte in den Nähten dazwischen.

Für Teams, die Agenten in ihre Pipeline holen, ist die praktische Konsequenz überschaubar: Behandelt jeden Agenten als eigenen Akteur mit eigener Identität, eigenen Rechten und einer klaren Antwort auf die Frage, wer ihn starten darf. Und lasst die Stelle, an der es unumkehrbar wird, beim Menschen. Genau diese Kontrollen haben im ADK-Repository verhindert, dass aus einer eleganten Angriffskette ein echter Schaden wurde.

Quellen3