Ein AI Coding Agent hat alle meine Projekte gelöscht – während er versuchte Laravel zu installieren

·

,

Ich teste derzeit verschiedene AI Coding Agents, um herauszufinden, wie autonom und effizient sie tatsächlich Software entwickeln können.

Die Aufgabe ist immer dieselbe:

Baue eine etwas komplexere PHP Webapplikation. – der Prompt ist natürlich etwas ausführlicher als das

Agents entscheiden sich bei solch einer Aufgabe oft für ein Framework wie Laravel.

Im Test habe ich aktuell:

Alle Agenten bekommen eine möglichst realistische Entwicklerumgebung. Kein künstliches Sandbox-Setup, sondern einfach ein Projektverzeichnis und typische Developer-Tools.

Zum Beispiel:

  • ein Workspace im Home-Verzeichnis unter ~/src
  • Git
  • Docker
  • Shell-Zugriff

Backups existieren natürlich.

Aber die Agenten wissen das nicht.


Ein wichtiges Detail des Testsystems

Ein Detail war dabei bewusst etwas ungewöhnlich:

Auf dem Host-System gibt es noch keine PHP Installation.

Das war Absicht. Ich wollte sehen, ob der Agent selbst erkennt, welche Laufzeitumgebung benötigt wird. Ich bin ja hier, ich kann ihm ja helfen!

Normalerweise würde ein Entwickler einfach PHP installieren:

sudo apt install php-cli

Der Agent konnte das allerdings nicht.

Er hatte keine sudo-Rechte und durfte keine Systempakete installieren.

Damit stand er vor einem klassischen Problem:

Laravel braucht PHP – aber PHP ist nicht vorhanden.


Wie der Agent versucht hat, seine Umgebung zu verstehen

Bevor der Agent überhaupt versuchte, Laravel zu installieren, begann er zunächst damit, das Hostsystem besser zu verstehen.

Dafür wollte er mehrere Dateien unter /etc lesen, unter anderem:

  • /etc/os-release
  • /etc/issue

Er hat dafür explizit um Erlaubnis gefragt, statt einfach auf die Dateien zuzugreifen. Das ist ein Sicherheitsmechanismus, den viele dieser Agents mitbringen – allerdings greift er nicht immer zuverlässig, wie wir gleich sehen.

Das zeigt zwei Dinge:

  1. Der Agent versucht aktiv, seine Umgebung zu analysieren.
  2. Er ist durchaus bereit, den Workspace zu verlassen, wenn er glaubt, dass es für seine Aufgabe relevant ist.

Die Lösung des Agents: Docker

Nachdem der Agent erkannt hatte, dass kein PHP vorhanden ist und er es nicht installieren kann, fand er eine alternative Lösung.

Er nutzte Docker, um eine eigene Laufzeitumgebung zu starten.

Zum Beispiel so:

docker run --rm \
  -v /home/kosmos/src:/workspace \
  -w /workspace \
  laravelsail/php82-composer \
  composer create-project laravel/laravel

Der Container bringt bereits mit:

  • PHP
  • Composer
  • die notwendigen Extensions

Damit konnte der Agent Laravel installieren, ohne etwas auf dem Host zu verändern.

Aus Sicht eines Entwicklers ist das sogar eine ziemlich vernünftige Lösung.


Der Incident

Während des Runs wollte der Agent ein Laravel-Projekt im Workspace erstellen.

Der Workspace war allerdings nicht leer, weil der Agent kurz zuvor selbst eine SPEC.md als Arbeitshilfe angelegt hatte.

Laravel (composer create-project) startet in diesem Fall nicht.

Ein menschlicher Entwickler würde jetzt wahrscheinlich einfach die vorhandene Datei verschieben oder temporär ein Unterverzeichnis im Workspace verwenden.

Der Agent entschied sich für eine andere Strategie.

Die Abfolge sah ungefähr so aus:

  1. Laravel-Projekt im übergeordneten Ordner ~/src erstellen
  2. versuchen, die Dateien von dort in den eigentlichen Workspace zu verschieben
  3. Konflikte feststellen

Und dann:

rm -rf *

Keine Nachfrage.
Keine Warnung.

Das komplette ~/src Verzeichnis war danach leer (fast).


Das eigentliche Risiko: Docker + root

Beim Analysieren des Runs fiel ein wichtiges Detail auf.

Die verwendeten Laravel-Container liefen als root.

Das ist bei vielen Docker Images leider Standard.

Solange ein Container isoliert bleibt, ist das kein großes Problem.

Sobald jedoch Host-Verzeichnisse gemountet werden, sieht die Sache anders aus.

Zum Beispiel:

docker run -v /home/kosmos/src:/workspace laravel-container

Der Container hat dann vollständigen Schreibzugriff auf dieses Verzeichnis.

Wenn der Prozess im Container als root läuft, gelten diese Rechte auch für alle Dateien im Mount.

Das führt häufig zu Nebenwirkungen wie:

  • root-owned Dateien
  • kaputte Berechtigungen
  • schwer löschbare Projektordner

Das zuvor erstellte laravel Projekt war als einziges noch in ~/src vorhanden, Verzeichnis und Dateien gehörten nämlich root.


Warum das theoretisch viel schlimmer hätte enden können

Docker verhindert nicht, dass ein Container größere Teile des Hostsystems mountet.

Zum Beispiel:

docker run -v /:/host ubuntu

Damit sieht der Container das komplette Dateisystem des Hosts unter /host.

Wenn der Prozess im Container als root läuft, kann er dort praktisch alles verändern.

Zum Beispiel:

rm -rf /host/*

Das würde nicht den Container zerstören.

Es würde den Host selbst löschen.

Das ist kein klassischer Container Escape.

Der Container nutzt einfach nur die Rechte, die ihm gegeben wurden.

Und wenn ein autonomer Agent:

  • Docker starten darf
  • Mounts frei setzen kann
  • Container als root laufen
  • und Shell-Befehle ausführen kann

dann ist der Unterschied zwischen

„Arbeite im Projektordner“

und

„Zerstöre das gesamte System“

plötzlich nur noch eine Frage des Mount-Pfads.


Selbst der Agent wusste später nicht mehr genau, was passiert ist

Ich habe den Agent gebeten den Incident selbst zu analysieren.

Ein interessantes Detail aus dem Incident-Report:

Der Agent konnte später nicht mehr vollständig rekonstruieren, was im Container passiert ist.

Der Grund war ein kleines, aber folgenreiches Detail.

Viele seiner Docker-Kommandos sahen ungefähr so aus:

docker run ... | tail -30

Damit wurde die Ausgabe von Anfang an auf die letzten 30 Zeilen begrenzt.

Das spart Tokens im Kontextfenster des Modells.

Der Nebeneffekt:

Der größte Teil der Container-Logs ging verloren.

Der Agent stellte im Incident-Report selbst fest, dass er deshalb nicht mehr nachvollziehen kann, welche Schritte genau im Container ausgeführt wurden.

Für den Incident ist dies aber nur ein nebensächliches Detail, denn das Löschen geschah in meinem Fall außerhalb des Containers.


Fazit

Dieser Test hat wieder mal bestätigt:

AI Coding Agents verhalten sich weniger wie Chatbots. Sie verhalten sich eher wie:

ein extrem schneller Junior-Developer auf Koks

Das kann unglaublich produktiv sein.

Aber auch gefährlich.

Vor allem wenn sie Zugriff haben auf:

  • Docker
  • das Dateisystem
  • automatische Toolchains
  • Container mit root-Rechten

Denn dann ist der Unterschied zwischen

composer create-project laravel

und

rm -rf *

manchmal nur eine Entscheidung im nächsten Token.

Der Agent mit dem das geschehen ist war übrigens Open Code mit dem kostenlosen „big pickle“ Model von OpenCode Zen, aber das ist hier Nebensache.

Und natürlich ist es ein generell bekanntes, aber gerade in Dev-Umgebungen oft akzeptiertes Sicherheitsrisiko, wenn eigentlich unprivilegierte User docker nutzen können.