Wie der Angriff funktioniert
GraphQL nutzt einen einzigen Endpunkt (oft /graphql), an den Clients beliebig strukturierte Queries (Lesen) und Mutations (Schreiben) senden. Mehrere Mechanismen werden missbraucht.
- Introspection - eine eingebaute Funktion, über die das Feld __schema das gesamte Schema inklusive aller Typen, Felder, Mutationen und Beschreibungen abfragbar macht; bleibt sie in Produktion aktiv, kann ein Angreifer die komplette API-Landkarte auslesen.
- Aliase - benannte Felder erlauben es, dasselbe Feld mehrfach in einer einzigen Query aufzurufen, was die Beschränkung umgeht, dass ein Objekt keine zwei Felder gleichen Namens haben darf.
- Batching - mehrere Operationen werden in einer HTTP-Anfrage gebündelt. Beide bündeln viele Operationen in einer HTTP-Nachricht, wodurch Rate Limiter, die nur HTTP-Anfragen zählen, umgangen werden - ideal für Brute Force von Login, OTP/2FA-Codes oder Discount-Codes.
- DoS - Queries haben eine Tiefe (verschachtelte Objekte) und eine Menge (z.B. first: 99999999); ohne Tiefen-, Mengen- oder Kostenlimits kann eine einzige teure Query Datenbank und Server überlasten.
- Fehlende Autorisierung - wenn die API Objekte direkt über per Argument übergebene IDs ausliefert, ohne zu prüfen, ob der Aufrufer Zugriff hat, entsteht IDOR/BOLA; Autorisierung muss pro Objekt und pro Feld geprüft werden.
Flexible Queries ohne Limits werden zur Angriffsfläche.
Beispiel
query isValidDiscount($code: Int) {
isValidDiscount(code:$code){
valid
}
isValidDiscount2:isValidDiscount(code:$code){
valid
}
isValidDiscount3:isValidDiscount(code:$code){
valid
}
}Auswirkung
Offene Introspection und aktive "Did you mean"-Feldvorschläge erleichtern das Auskundschaften der gesamten API inklusive ungewollt exponierter privater Felder (z.B. E-Mail-Adressen, User-IDs).
Batching/Alias-Angriffe ermöglichen schnelles, schwer erkennbares Brute Forcing von Passwörtern, 2FA-/OTP-Codes, Tokens und die Enumeration von Objekten - und umgehen dabei häufig Rate Limiter und Schutzmechanismen, die nur HTTP-Anfragen zählen, da nur eine einzige Anfrage sichtbar ist.
Teure oder tief verschachtelte Queries führen zu Denial of Service (Erschöpfung von CPU, Speicher, Datenbank oder Downstream-Diensten).
Fehlende objekt-/feldbezogene Autorisierung erlaubt unbefugten Daten- und Schreibzugriff (IDOR/BOLA/BFLA), im schlimmsten Fall bis hin zur Rechteausweitung.
So schützt man sich
- Introspection und Schema-Explorer wie GraphiQL in Produktion bzw. für nicht authentifizierte/autorisierte Nutzer deaktivieren (system-weit, wenn die API nur intern genutzt wird).
- Feldvorschläge ("Did you mean ...?"-Suggestions) deaktivieren, damit das Schema nicht trotz deaktivierter Introspection erraten werden kann.
- Batching-/Alias-Angriffe begrenzen: objektbezogenes Rate Limiting im Code, sowie die Anzahl gleichzeitig ausgeführter Operationen begrenzen (laut OWASP kein Allheilmittel, aber eine wirksame Maßnahme).
- DoS verhindern: Tiefenlimit (depth limit) und Mengenlimit setzen, Paginierung erzwingen, maximale Query-Größe begrenzen, Query-Cost-Analyse mit maximalem Kostenlimit, plus Timeouts auf Anwendungsebene.
- Autorisierung auf Objekt- und Feldebene durchsetzen (RBAC), auch auf edges UND nodes; Besitz einer Objekt-ID darf niemals Zugriff implizieren (gegen IDOR/BOLA/BFLA).
- Strikte Input-Validierung mit Allow-List und spezifischen GraphQL-Typen (Scalars/Enums, eigene Validatoren) gegen Injection und DoS.
- Keine übermäßigen Fehlermeldungen zurückgeben (Debug-Modus und Stack Traces in Produktion abschalten).
- CSRF verhindern: Cross-Site-Request-Forgery-Schutz einsetzen (Validierung von Content-Type/Anfrageformat, CSRF-Token).
Quellen
- GraphQL Cheat Sheet OWASP Cheat Sheet Series, 2025
- GraphQL API vulnerabilities PortSwigger Web Security Academy, 2025