Fault Injection für LiteLLM: das Plugin zu AI Fault Projection

26. August 2026 · von Melchior Limacher · AI Security Security Awareness Open Source

Vom Konzept zum Werkzeug: ein Callback im LLM-Proxy, der kontrollierte Fehlantworten einspielt – markiert, protokolliert und messbar.

Im vorangegangenen Beitrag haben wir AI Fault Projection beschrieben: das Prinzip von Phishing-Simulation und Threat Image Projection, übertragen auf die KI-Antwort. Wer täglich korrekte Ausgaben bekommt, prüft mit der Zeit nicht mehr. Gegen diesen Aufmerksamkeitsverfall hilft dieselbe Medizin wie gegen Phishing-Blindheit: seltene, kontrollierte, danach aufgelöste Einspielungen im Arbeitsalltag.

Auf die konzeptionelle Frage folgte in Gesprächen regelmässig die praktische: Womit denn? Wir haben deshalb eine Referenzimplementierung gebaut und quelloffen gestellt.

Zwei Hälften: einspielen und messen

Die Manipulation allein bringt nichts. Ein Trainingsinstrument entsteht erst, wenn man erfährt, wie die Nutzenden reagiert haben. Das Plugin protokolliert deshalb, was gefälscht wurde; ein separater kleiner Dienst nimmt entgegen, wie darauf reagiert wurde; ein Auswertungsskript verbindet beides zur Erkennungsrate je Fehlertyp.

Die Reaktion wird über POST /feedback mit einem der Signale noticed, corrected, reasked, thumbs_down oder none gemeldet – ausgelöst etwa durch einen Knopf im Assistenten-Frontend oder durch einen Auswerter im Nachgang. Der Schlüssel für die Verknüpfung ist die Completion-ID aus der Antwort (chatcmpl-…), also genau die Kennung, die auch der Client zu sehen bekommt.

Der Eingriffspunkt: Hooks im Proxy

Grundlage ist der Aufbau aus dem letzten Beitrag: ein LLM-Proxy zwischen Belegschaft und Sprachmodell, den ein Unternehmen für Data Loss Prevention und Kostenkontrolle ohnehin betreibt. Das Plugin ist eine CustomLogger-Unterklasse und hängt sich an drei Stellen ein:

Client → LiteLLM Proxy → Provider
              ↑
      FaultInjector (CustomLogger)
      ├─ async_post_call_success_hook             # ohne Streaming: Inhalt ersetzen
      ├─ async_post_call_streaming_iterator_hook  # Streaming: puffern → injizieren → neu ausgeben
      └─ async_post_call_response_headers_hook    # Marker x-fault-injected (Behelf)
              │
              ├─ Ziel-Prüfung, dann Stichprobe
              ├─ injectors/ (mechanisch | LLM-gestützt)
              └─ Audit → injections.jsonl

feedback_api.py  → feedback.jsonl     # Reaktionen, Schlüssel: Antwort-ID
report.py        → Verknüpfung beider Logs → Erkennungsrate je Fehlertyp

Der Post-Call-Hook sieht die bereits normalisierte Antwort – dasselbe Objekt, unabhängig davon, ob dahinter ein lokales Modell, Azure OpenAI oder Anthropic steht. Das ist der Grund für diese Wahl: ein globaler Handler statt anbieterspezifischer Sonderfälle. Manipuliert wird choices[0].message.content.

Konfiguration

Registriert wird der Callback in der Proxy-Konfiguration; alles Verhaltensrelevante steht unter fault_injection::

litellm_settings:
  callbacks: ["fault_injector.FaultInjector"]

fault_injection:
  enabled: true                 # Kill-Switch
  inject_rate: 0.1              # Anteil der manipulierten Antworten
  deterministic: false          # true → nur mechanische Injektoren, fester Seed
  seed: 1337

  error_types:                  # relative Gewichte
    factual: 0.4
    fake_source: 0.3
    logic_break: 0.2
    bad_code: 0.1

  llm_injector:
    model: "gpt-4o-mini"
    max_len_delta: 0.25         # Umschrift verwerfen, wenn die Länge zu stark driftet

  targets:                      # Wirkungsbereich, greift VOR der Stichprobe
    allow_key_aliases: ["redteam-*"]
    deny_topics: ["medical", "legal", "financial"]

  audit_log_path: "./audit/injections.jsonl"
  feedback_log_path: "./audit/feedback.jsonl"

Die Voreinstellung inject_rate: 0.1 dient dem Ausprobieren. Im Betrieb gilt, was wir im Konzeptbeitrag zur Dosierung geschrieben haben: selten, gezielt, lehrreich. Wer jede zehnte Antwort verfälscht, zerstört die Produktivität, die er schützen will.

Der Kill-Switch enabled lässt sich über die Umgebungsvariable FAULT_INJECTION_ENABLED übersteuern, allerdings nur in eine Richtung: Ein falscher Wert schaltet die Injektion ab, ein wahrer Wert kann eine deaktivierte Konfiguration nicht scharf schalten. Ein versehentlich gesetztes Flag in einer Umgebung kann damit nichts einschalten.

Die vier Injektoren

Jeder Injektor bildet ein reales Fehlermuster ab, das ein eigenes Prüfsignal hat. Zwei arbeiten rein mechanisch, zwei ziehen ein Sprachmodell hinzu:

Die beiden LLM-gestützten Injektoren rufen ihr Modell direkt über das SDK auf, nicht über den Proxy, und markieren diesen Aufruf so, dass er von der Injektion ausgenommen bleibt – sonst würde sich das Werkzeug selbst manipulieren. Beide scheitern zudem sicher: Kommt eine unveränderte, leere oder in der Länge stark abweichende Umschrift zurück, wird sie verworfen und die Originalantwort durchgereicht; protokolliert wird das als übersprungen.

Mit deterministic: true bleiben nur die mechanischen Injektoren aktiv, mit festem Seed und damit reproduzierbar. In diesem Modus läuft auch die Testsuite.

Marker und Audit-Log

Jede Injektion wird als eine Zeile JSONL festgehalten: Zeitpunkt, Antwort-ID, Fehlertyp, Originalinhalt und manipulierter Inhalt. Das ist die einzige verlässliche Grundlage dafür, einer betroffenen Person hinterher zu zeigen, was genau verändert wurde.

Zusätzlich trägt eine manipulierte Antwort den HTTP-Header x-fault-injected. Dessen Zuverlässigkeit ist geteilt, und das gehört offen gesagt: Bei nicht gestreamten Antworten wird der Marker an den Antwortparametern gesetzt und beim Serialisieren in die Header übernommen, unabhängig von der Reihenfolge der Hooks. Bei gestreamten Antworten sind die Header bereits abgeflossen, bevor der Rumpf entsteht – dort bleibt der Marker ein Behelf. Massgeblich für den Debrief ist deshalb das Audit-Log, in beiden Fällen.

Wir haben im Konzeptbeitrag geschrieben: Bleibt die Auflösung aus oder kommt sie zu spät, hat man realen Schaden angerichtet statt vor ihm zu schützen. Das Audit-Log ist die technische Übersetzung dieses Satzes. Wer das Plugin ohne funktionierenden Debrief-Pfad betreibt, verfälscht Arbeitsergebnisse seiner Belegschaft ohne Gegenwert.

Wirkungsbereich eingrenzen

Vor der Stichprobenentscheidung steht eine Ziel-Prüfung. Sie ist bewusst restriktiv ausgelegt: Ohne Eintrag in der Positivliste ist nichts angreifbar. Zwei Mechanismen greifen ineinander, und sie sind unterschiedlich belastbar:

Positivliste der Schlüssel-Aliase (allow_key_aliases) – nur Anfragen über bestimmte virtuelle Schlüssel sind überhaupt Kandidaten. Das ist die eigentliche Begrenzung des Wirkungsbereichs: Man richtet dedizierte Schlüssel für die Übung ein und lässt sie ausschliesslich auf unkritische Anwendungsfälle zeigen.

Themen-Sperrliste (deny_topics) – eine Textsuche über den Prompt. Sie ist ein Komfortfilter und keine Sicherheitsgrenze: Eine Anfrage, deren Wortlaut kein Stichwort enthält, deren Antwort aber folgenreich ist, rutscht durch. Wer sich darauf verlässt statt auf die Positivliste, hat den Wirkungsbereich nicht im Griff.

Grenzen, die man vorher kennen sollte

Vor dem Einsatz: die Leitplanken

Die technischen Hürden sind niedrig, die organisatorischen sind es nicht. Bevor ein solches Plugin in einem produktiven Assistenten läuft, gehören drei Dinge geklärt:

Ankündigung. Die Belegschaft muss grundsätzlich wissen, dass Simulationen stattfinden – offen bleibt allein der Zeitpunkt.

Rechtsrahmen. Wer individuelle Trefferquoten erfasst, bewegt sich im Bereich von Art. 26 ArGV 3, des Datenschutzes und der betrieblichen Mitwirkung. Die aggregierte Auswertung ist der einfachere und meist ausreichende Weg.

Wirkungsbereich. Kein Szenario, dessen Fehlübernahme sich nicht rückgängig machen lässt, und kein Übergriff in Vorgänge mit Aussenwirkung. Technisch heisst das: Positivliste eng halten, dedizierte Schlüssel verwenden.

Ein Wort zur Lieferkette

Wer einen LLM-Proxy einsetzt, stellt eine Komponente in den Pfad sämtlicher KI-Kommunikation – mit Zugriff auf Anfragen, Antworten und Anbieter-Schlüssel. Wie exponiert diese Position ist, hat der Vorfall vom 24. März 2026 gezeigt: Über kompromittierte PyPI-Konten gelangten zwei manipulierte LiteLLM-Versionen (1.82.7 und 1.82.8) am regulären Release-Workflow vorbei auf den Paketindex. Sie führten beim Import beziehungsweise beim Start jedes Python-Prozesses Schadcode aus, sammelten Zugangsdaten ein und versuchten, sich in Kubernetes-Cluster auszubreiten (Analyse bei ARMO). Als letzte unbelastete Fassung galt 1.82.6.

Für den Betrieb folgt daraus das Übliche, hier aber mit erhöhtem Einsatz: Versionen festnageln, Hashes verifizieren, Updates bewusst einspielen und dem Proxy keine Rechte geben, die er nicht braucht – insbesondere keine Service-Account-Tokens, mit denen sich seitlich in ein Cluster ausbreiten lässt. Unser Plugin pinnt litellm[proxy] aus zwei Gründen exakt: wegen der Lieferkette und weil sich die Hook-Schnittstelle des Proxys laufend ändert. Ein Integrationstest fährt die Hooks gegen ein echtes Antwortobjekt der installierten LiteLLM-Version, damit ein Versionssprung auffällt, statt still die Manipulation oder die Protokollierung zu brechen.

Lizenz und Repository

Der Code steht unter AGPL-3.0-or-later. Die Wahl ist bewusst: Ein Proxy ist Netzwerksoftware, und die AGPL erstreckt die Copyleft-Pflicht auch auf das Anbieten über ein Netz. Wer das Plugin verändert und als Dienst betreibt, gibt seine Änderungen weiter. LiteLLM selbst steht unter der permissiven MIT-Lizenz, was diese Kombination zulässt.

Repository: github.com/Limacher-Informationssicherheit-GmbH/litellm-ai-fault-injector. Installation, sämtliche Konfigurationsoptionen und die vollständige Liste der Einschränkungen stehen im README des Plugins, der Hook-Lebenszyklus und die Entwurfsentscheidungen in ARCHITECTURE.md. Fehlerberichte und weitere Injektor-Strategien sind willkommen.

Fazit

Die Technik hinter AI Fault Projection ist überschaubar: ein Callback, ein Protokoll, eine Auswertung. Der Aufwand steckt in der Frage, welche Szenarien realistisch sind, wie selten sie eingespielt werden, wie eng der Wirkungsbereich gezogen ist und wie zuverlässig die Auflösung erfolgt. Das Plugin nimmt die technische Hürde weg, damit diese Fragen den Platz bekommen, den sie brauchen.


Wir begleiten Piloten von der Machbarkeits- und Rechtsprüfung über die Proxy-Anbindung bis zum ersten Durchlauf in einem Team. Wer AI Fault Projection ausprobieren möchte, findet bei Limacher IT-Security gerne Unterstützung.

← AI Fault Projection: Phishing-Simulationen für KI-Antworten Alle Beiträge