TL;DR: Die Eingabe Ihrer API ist eine Angriffsfläche – testen Sie sie auch so. Schreiben Sie Negativtests für übergroße Felder, falsche Typen, fehlerhafte Bodies und Injektionsstrings. Stellen Sie sicher, dass der Endpunkt einen 4xx und niemals einen 5xx zurückgibt. Machen Sie Schema-Validierung mit
additionalProperties: false, Enums und Längenbeschränkungen zu einer Sicherheitskontrolle. Führen Sie die gesamte Suite bei jeder Änderung im CI aus. KI-Agenten erhöhen die Dringlichkeit: Sie generieren und leiten Payloads mit Maschinengeschwindigkeit weiter. So wird aus „diese Daten laden“ schnell „diesen Code ausführen“ – und zwar skalierbar.
Die meisten Testsuiten beweisen nur, dass eine API bei gültigen Eingaben funktioniert: gültigen Body senden, 200 erhalten, Assertion bestanden. Das sagt wenig darüber aus, was bei feindseligen Eingaben passiert. Unvertrauenswürdige Eingaben sind alle Daten, die Ihr Endpunkt nicht selbst erzeugt hat: Request-Bodies, Query-Strings, Header, Datei-Uploads, Webhook-Payloads und JSON, das ein KI-Agent ad hoc erstellt. Behandeln Sie jede dieser Quellen so, als würde irgendwann die schlechteste mögliche Variante eintreffen.
Apidog noch heute ausprobieren
Im Juli 2026 beschrieb Hugging Face einen Sicherheitsvorfall, dessen Angriffsvektor Daten statt gestohlener Passwörter waren. Die Lehren aus dieser Verletzung haben wir separat behandelt; dieser Beitrag konzentriert sich auf die Umsetzung.
Sie erstellen hier Tests, die Eingaben wie ein Angreifer senden, und führen diese bei jeder Änderung automatisch aus. Die Kategorien orientieren sich an den OWASP API Security Top 10. Apidog kann den Vertrag und die Tests verwalten, die Vorgehensweise funktioniert aber mit jedem Framework.
Eingabe ist eine Angriffsfläche, kein Formularfeld
Validierung wird oft als UX-Detail behandelt: leere E-Mail abfangen, Fehlermeldung anzeigen, fertig. Für APIs reicht das nicht. Jedes Feld, das Ihre API akzeptiert, ist ein Vertrag, den ein Aufrufer brechen kann.
Beispiele:
- Aus einem kleinen Integer für
limitwird999999999. - Aus einem erwarteten Dateinamen wird
../../etc/passwd. - Aus einem
config-Objekt mit Einstellungen wird eine Sammlung von Anweisungen.
Sicherheitstests sind keine separate Aktivität am Ende eines Projekts. Es sind Negativtests für die Felder, die den größten Schaden verursachen können.
Stellen Sie für jedes akzeptierte Feld dieselbe Frage:
Was ist das Schlimmste, das in dieses Feld passen kann?
Diese Denkweise ist die Grundlage von API-Sicherheits-Best-Practices. Der Rest dieses Beitrags übersetzt sie in ausführbare Tests.
Wie aus „diese Daten laden“ „diesen Code ausführen“ wurde
Der Vorfall bei Hugging Face zeigt, warum Eingaben diese Aufmerksamkeit benötigen. Laut Hugging Face waren manipulierte Datensätze der Angriffsvektor: Ein bösartiger Datensatz löste einen Remote-Code-Datensatzlader aus, außerdem enthielt eine Datensatzkonfiguration eine Template-Injektion. Details finden Sie im Sicherheitsvorfallbericht von Hugging Face.
Das Muster ist entscheidend:
- Ein Endpunkt akzeptiert etwas, das als Daten beschrieben wird.
- Das Laden dieser Daten aktiviert einen Codepfad.
- Der Codepfad interpretiert angreifergesteuerte Anweisungen.
Damit wird aus „diese Daten laden“ effektiv „diesen Code ausführen“.
Dasselbe gilt im kleineren Maßstab für Template-Injektionen: Ein Konfigurationswert sollte inert sein, wird aber evaluiert. Text wird dadurch zur Ausführung.
Jeder Endpunkt, der Loader-Namen, Formate, Templates, serialisierte Objekte oder Konfigurations-Blobs akzeptiert, kann unbeabsichtigt Anweisungen akzeptieren. Wenn Sie nie eine feindselige Konfiguration an diesen Endpunkt gesendet haben, haben Sie nicht überprüft, ob die Eingabe tatsächlich inert bleibt.
Schema-Validierung als Sicherheitskontrolle
Die günstigste Schutzmaßnahme ist ein striktes Schema an der API-Grenze. Ein Schema ist nicht nur Dokumentation. Wenn Sie alles ablehnen, was nicht dem Schema entspricht, wird es zum Filter vor Ihrer Geschäftslogik.
JSON Schema liefert dafür die notwendigen Bausteine.
Beispiel für eine Dataset-Konfiguration:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"additionalProperties": false,
"required": ["loader", "name"],
"properties": {
"loader": { "enum": ["csv", "json", "parquet"] },
"name": {
"type": "string",
"maxLength": 128,
"pattern": "^[\\w .-]+$"
},
"rows": {
"type": "integer",
"minimum": 0,
"maximum": 1000000
}
}
}
Dieses Schema enthält mehrere konkrete Abwehrmaßnahmen:
| Regel | Wirkung |
|---|---|
additionalProperties: false |
Lehnt eingeschmuggelte Felder wie template ab. |
enum für loader
|
Akzeptiert nur bekannte Loader und blockiert Werte wie pickle://. |
maxLength |
Begrenzung gegen Multi-Megabyte-Strings und Speicherverbrauch. |
pattern für name
|
Blockiert unerwartete Zeichenfolgen wie {{ oder '; DROP TABLE. |
minimum und maximum
|
Verhindern unrealistische oder gefährliche Zahlenwerte. |
Keiner dieser Einträge muss Angreifer kennen. Sie akzeptieren lediglich den engen Satz von Eingaben, den Ihre Anwendung tatsächlich unterstützt. Genau diese Einschränkung ist die Sicherheitseigenschaft.
Schema-Validierung verhindert nicht jeden Exploit. Sie schließt aber eine häufige Fehlerklasse: Endpunkte, bei denen nie explizit definiert und geprüft wurde, was sie akzeptieren.
Negativtests: Beweisen, dass der Endpunkt „Nein“ sagt
Happy-Path-Tests prüfen, dass gute Eingaben gute Ausgaben erzeugen. Negativtests prüfen, dass schlechte Eingaben kontrolliert abgelehnt werden.
Eine kontrollierte Ablehnung ist ein Feature:
-
400 Bad Requestoder422 Unprocessable Entity: Die API verteidigt ihre Grenze. -
413 Payload Too Large: Die API begrenzt Ressourcenverbrauch. -
500 Internal Server Error: Feindselige Eingabe hat Logik erreicht, die darauf nicht vorbereitet war.
Erstellen Sie Negativfälle systematisch. Prüfen Sie pro Feld mindestens:
- falscher Typ
- fehlender Pflichtwert
- verbotenes zusätzliches Feld
- zu langer Wert
- Wert außerhalb des erlaubten Bereichs
- feldspezifische Injektionsstrings
Für jede Antwort sollten Sie zwei Assertions haben:
Status ist ein erwarteter 4xx-Code.
Status ist niemals ein 5xx-Code.
Die API-Sicherheitstest-Checkliste bietet dafür eine feldspezifische Startliste.
Prüfen Sie dabei Verhalten statt Fehlertexte. Ein Test, der exakt auf "ungültiger Loader" besteht, bricht bei einem harmlosen Refactoring. Prüfen Sie stattdessen:
- Statuscode
- fehlende Nebenwirkungen
- keine sensitiven Daten in der Antwort
- keine unerwartete Auswertung oder Transformation der Eingabe
Injektionsklassen mit eigenen Testfällen
Sie benötigen nicht Hunderte Payloads pro Endpunkt. Beginnen Sie mit mindestens einem repräsentativen Test pro Injektionsklasse. So schlagen Regressionen sichtbar fehl.
Tools für automatisierte API-Schwachstellen-Erkennung können später zusätzliche Varianten abdecken. Die folgenden handgeschriebenen Fälle fangen jedoch offensichtliche Lücken schnell ab.
SQL-Injektion: Senden Sie
1); DROP TABLE datasets;--in Felder, die Datenbankabfragen beeinflussen. Der Endpunkt sollte den Wert als Literal behandeln, kontrolliert ablehnen oder ein leeres Ergebnis liefern – aber niemals einen Datenbankfehler offenlegen.Template-Injektion: Senden Sie
{{ 7*7 }}und{{ config.__class__ }}in Namens-, Label- oder Beschreibungsfelder. Enthält die Antwort49, wurde die Eingabe von einer Template-Engine evaluiert.Unsichere Deserialisierung und Remote-Code-Lader: Senden Sie
pickle://als Loader oder serialisierte Objekte an Stellen, die einfache Werte erwarten. Unbekannte Loader müssen per Whitelist abgelehnt werden.Befehlsinjektion: Senden Sie
; idund$(id)in Felder, die zu Shell-Argumenten werden könnten, etwa Dateinamen oder Konvertierungsoptionen. Ein erfolgreicher Request, der Prozessinformationen preisgibt, ist ein kritischer Befund.
Übergroße, fehlerhafte und falsch deklarierte Bodies testen
Nicht jede feindselige Eingabe ist ein cleverer String. Übergroße oder fehlerhafte Bodies können Parser und Infrastruktur erreichen, bevor Ihre Validierungslogik ausgeführt wird.
Testen Sie mindestens diese Fälle:
- Ein einzelnes Feld mit 5 MB desselben Zeichens
- Ein JSON-Array mit 1.000.000 Elementen
- Abgeschnittenes JSON
- JSON mit nachgestelltem Komma
- Sehr tief verschachteltes JSON
Erwartetes Verhalten:
| Fall | Erwartete Antwort |
|---|---|
| Body überschreitet Größenlimit | 413 Payload Too Large |
| Ungültiges oder abgeschnittenes JSON | schneller 400 Bad Request
|
| Extrem tiefe Verschachtelung | kontrollierter 400 oder 413, kein hängender Worker |
| Unerwarteter Datentyp |
400 oder 422
|
Prüfen Sie außerdem Content-Type-Verwirrung:
Content-Type: application/json
Senden Sie dazu absichtlich XML als Body. Wiederholen Sie den Test umgekehrt:
Content-Type: application/xml
Senden Sie dann JSON oder eine XML-Payload mit externer Entität, um XXE-bezogene Verarbeitung zu prüfen. Testen Sie außerdem JSON mit Content-Type: text/plain.
Der Server sollte Header und Body konsistent prüfen, bevor er Inhalte parst. Eine Nichtübereinstimmung sollte nicht stillschweigend akzeptiert werden.
Warum KI-Agenten die Einsätze erhöhen
Die beschriebenen Risiken existierten bereits vor KI-Agenten. Agenten verändern jedoch Volumen und Geschwindigkeit.
Ein menschlicher Angreifer sendet Requests nacheinander. Ein KI-Agent kann Payloads generieren, variieren und mit Maschinengeschwindigkeit weiterleiten. Dabei entstehen Feldwerte, die kein Mensch geschrieben und kein manueller Test vorhergesehen hat.
Drei Eigenschaften erhöhen das Risiko:
- Synthetisierte Eingaben: Agenten erzeugen neue Kombinationen und Werte außerhalb normaler Nutzerpfade.
- Wiederholung und Verkettung: Ein vergiftetes Upstream-Dokument kann in Sekunden Tausende Requests auslösen.
- Weitergabe über Vertrauensgrenzen: Daten aus Datensätzen, Webhooks oder externen Tools werden als echte API-Anfragen weitergereicht.
Das Hugging-Face-Muster – „diese Daten laden“ wird zu „diesen Code ausführen“ – ist genau die Art von Anweisung, die ein Agent unbemerkt über eine Vertrauensgrenze transportieren kann.
Der Beitrag zu Prompt-Injection für API-Teams behandelt diese Übergaben detaillierter.
Die Verteidigung bleibt gleich: strikte Verträge, kontrollierte Ablehnungen und automatische Tests. Manuelle Prüfung reicht bei Agentenverkehr nicht aus.
Negativsuite erstellen und bei jeder Änderung im CI ausführen
Überführen Sie die Fälle in eine Testsuite, die bei jedem Pull Request läuft. Dieses pytest-Beispiel prüft einen Staging-Endpunkt auf kontrollierte Ablehnungen:
import httpx
import pytest
BASE = "https://staging.internal/v1"
HOSTILE_CONFIGS = [
{"loader": "pickle://s3/models/payload.pkl", "format": "auto"},
{"loader": "csv", "name": "{{ 7*7 }}"},
{"loader": "csv", "name": "{{ config.__class__ }}"},
{"loader": "csv", "filter": "1); DROP TABLE datasets;--"},
{"loader": "csv", "name": "A" * 5_000_000},
]
@pytest.mark.parametrize("config", HOSTILE_CONFIGS)
def test_dataset_config_is_refused(config):
response = httpx.post(
f"{BASE}/datasets",
json={"config": config},
timeout=10,
)
assert response.status_code in (400, 413, 422), response.text
assert response.status_code < 500, (
"Ein 5xx bedeutet, dass die Payload Logik erreicht hat, "
"die sie nicht erreichen sollte."
)
assert "49" not in response.text, (
"Template wurde gerendert: mögliche Server-Side Template Injection."
)
Ergänzen Sie bei Endpunkten mit Nebenwirkungen zusätzlich eine Prüfung, dass kein Objekt erstellt, verändert oder gelöscht wurde.
Ein minimaler GitHub-Actions-Job führt die Tests bei Pushes und Pull Requests aus:
name: api-abuse-tests
on: [push, pull_request]
jobs:
negative-input:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: pytest tests/negative_input.py -q
Damit blockiert ein gelockerter Validator den Merge, statt später in Produktion aufzufallen.
Ein schemaorientiertes Tool kann diesen Workflow vereinfachen. In Apidog definieren Sie Endpunkte über einen OpenAPI-Vertrag und prüfen Requests sowie Responses gegen diesen Vertrag. Speichern Sie Negativszenarien direkt neben Happy-Path-Szenarien:
- übergroße Felder
- falsche Typen
- zusätzliche verbotene Eigenschaften
- SQL-, Template- und Command-Injection-Strings
- erwartete 4xx-Statuscodes
Führen Sie dieselben Szenarien anschließend über die Apidog CLI im CI aus. Wenn Sie starten möchten, können Sie Apidog herunterladen und für einen bestehenden Endpunkt ein Negativszenario ergänzen.
Beachten Sie die Grenze: Apidog ist ein Tool für Design, Tests, Mocks und Dokumentation. Es ersetzt keine Web Application Firewall, filtert keinen Live-Traffic und ersetzt kein SIEM. Vertragsvalidierung während Tests fängt ebenfalls nicht jeden Exploit ab. Sie macht aber explizit, was ein Endpunkt akzeptiert, und verhindert die Fehlerklasse „Wir haben nie geprüft“.
Häufig gestellte Fragen
Was ist der Unterschied zwischen Negativtests und Fuzzing?
Negativtests senden bewusst ausgewählte ungültige Eingaben – typischerweise einen Fall pro Fehlerklasse. Fuzzing sendet große Mengen zufälliger oder mutierter Eingaben, um unbekannte Fälle zu finden.
Beginnen Sie mit Negativtests: Sie sind schnell, deterministisch und einfach im CI ausführbar. Ergänzen Sie Fuzzing, wenn Sie zusätzliche Breite über Ihre bekannten Annahmen hinaus benötigen.
Sollten diese Tests gegen Produktion laufen?
Nein. Führen Sie sie gegen Staging oder eine isolierte Testumgebung aus. Übergroße Payloads und Command-Injection-Sonden sind absichtlich belastend. Bei Fehlern könnten einige Tests außerdem Daten verändern.
Eine dedizierte Umgebung erlaubt aggressive Tests ohne Risiko für echte Nutzer.
Fängt eine WAF diese Fälle nicht ohnehin ab?
Eine WAF ist eine sinnvolle zusätzliche Verteidigungsschicht, aber kein Ersatz für Eingabevalidierung in der Anwendung. WAF-Regeln können umgangen werden und kennen Ihre Geschäftslogik nicht.
Diese Tests beweisen, dass der Endpunkt selbst „Nein“ sagt – statt dass Sie sich ausschließlich auf einen vorgelagerten Filter verlassen.
Wie viele Negativfälle brauche ich pro Endpunkt?
Zielen Sie auf mindestens einen Fall pro Feld und relevanter Fehlerklasse:
- falscher Typ
- Wert außerhalb des Bereichs
- zu langer Wert
- verbotenes Feld
- fehlender Pflichtwert
- zum Feldformat passende Injektionsstrings
Das sind meist nur einige wenige Fälle pro Endpunkt. Die Abdeckung der Fehlerklassen ist wichtiger als die absolute Anzahl.
Stoppt Schema-Validierung Injektionen vollständig?
Nein. Ein striktes Schema reduziert fehlerhafte, übergroße und unerwartete Eingaben und blockiert nicht erlaubte Felder. Ein Wert kann jedoch schema-konform sein und trotzdem eine SQL- oder Template-Injektion enthalten.
Behalten Sie deshalb weitere Schutzschichten bei:
- parametrisierte Datenbankabfragen
- sichere Deserialisierung
- korrektes Output-Encoding
- restriktive Loader-Whitelists
- Ressourcenlimits für Body-Größe, Zeit und Verschachtelung
Das Schema reduziert die Angriffsfläche, die diese Schichten verteidigen müssen.
Top comments (0)