Web/API-PentestFabian Gold7 min Lesezeit

Schwachstellen in GraphQL - Überblick und Fallbeispiele

Diese Auskunftsfähigkeit von GraphQL ist sowohl Stärke als auch Schwäche zugleich und sollte entsprechend getestet werden.

Inhaltsverzeichnis

Was ist GraphQL?

GraphQL ist eine Abfragesprache für APIs. Wie es der Name schon beschreibt, ist sie gut geeignet für die Abfrage von Daten, welche als Graph dargestellt werden können. Verglichen zu den bisher meist verwendeten Rest APIs liefert GraphQL einige Vorteile, welche im folgenden Abschnitt beschrieben werden. Um die beiden Technologien jedoch besser vergleichen zu können, wird die Funktionsweise beider kurz beschrieben.

Eine Rest API besteht aus einer Reihe von Endpunkten, die Anzahl variiert je nachdem welche Daten der Clients abfragen kann. Jeder Endpunkt ist gemapped mit einer Entität und gibt Informationen zu dieser Entität an den Client zurück. Wenn ein Client Informationen zu mehreren Entitäten abfragen möchte, muss er für jede Entität eine Anfrage an deren Endpunkt stellen, dies ist im Vergleich zu GraphQL sehr inperformant und führt zu einem erhöhten Verwaltungsaufwand.

In GraphQL gibt es nur einen Endpunkt mit dem der Client kommuniziert. Der Client stellt eine Anfrage und erhält eine Antwort. Diese Auskunftsfähigkeit von GraphQL ist sowohl Stärke als auch Schwäche zugleich. Eine Rest API begrenzt die Informationen, die mit einer einzigen Anfrage abgefragt werden können, indem sie die Auskunftsfähigkeit eines Endpunkts beschränkt. GraphQL unterstützt beliebige Abfragen über die Daten, so dass eine einzige Abfrage eine große Menge an Daten liefern kann.

Schema von GraphQL

Zur Beschreibung der Daten verwendet GraphQL ein sogenanntes Schema. Das Schema legt genau fest, welche Abfragen und Mutationen für Clients verfügbar sind.

Zusätzlich gibt es das sogenannte Introspektionsschema, welches verwendet wird um eine GraphQL Anwendung nach Informationen darüber zu fragen, welche Abfragen unterstützt werden. Das Introspektionsschema kann mit der Abfrage ausgegeben werden. Um das Introspektionsschema abzufragen, können auch verschiedene GraphQL-IDEs oder zum Beispiel auch GraphQL Voyager verwendet werden.

Schwachstellen und wie man sie verhindern kann

Basierend auf Angaben der OWASP Foundation sind die häufigsten Angriffe gegen GraphQL:

  • Injection - dies umfasst unter anderem SQL- und NoSQL Injection, OS-Command Injection, SSRF (Server Side Request Forgery) und CRLF (Carriage Return Line Feed) Injection/Request Smuggling
  • DoS (Denial of Service)
  • Ausnutzen schwacher Autorisierung
  • Batching-Angriffe, eine GraphQL-spezifische Methode des Brute-Force-Angriffs
  • Missbrauch von unsicheren Standardkonfigurationen

Injektion

GraphQL selbst bietet keinen Schutz vor Angriffen. Wenn also kein Schutz eingebaut wurde, z.B. keine parametrisierten Abfragen, kann die Anwendung anfällig für jegliche Art von Injection Angriffe sein. Deshalb sollten alle eingehenden Daten validiert werden um sicherzustellen, dass nur gültige Werte zugelassen werden. Ungültige Eingaben sollten stets abgelehnt werden, ohne dabei übermäßige Informationen über die Funktionsweise der API preiszugeben. Des Weiteren sollten parametrisierte Abfragen im Backend verwendet werden, um die vom Benutzer gelieferten Daten zu verarbeiten. Zusätzlich sollte sichergestellt werden, dass der Client, der die Daten aus der GraphQL-Antwort rendert, vor dem Rendering die Daten bereinigt. Und die Implementierung einer angemessenen Content-Security Policy schadet sowieso nie.

Denial of Service

DoS ist ein Angriff auf die Verfügbarkeit und Stabilität der API, der dazu führen kann, dass sie langsam ist, nicht mehr reagiert oder gar nicht mehr verfügbar ist. Deshalb ist es ratsam, eine Paginierung zur Begrenzung der Datenmenge, die in einer Antwort zurückgegeben werden kann, einzubauen. Des Weiteren wäre die Verwendung eines Rate Limiters pro User bzw. pro IP sinnvoll.

Ausnutzen schwacher Autorisierung
Das Ausnutzen einer schwachen Autorisierungslogik ist das bei Weitem häufigste Problem einer GraphQL-basierten Anwendung. Grundsätzlich ist es wichtig Authentifizierungs- und Autorisierungsmethoden zu implementieren. Jede Anfrage eines Clients sollte darauf überprüft, ob der Client berechtigt ist die Daten zu lesen.

Batching-Angriffe

GraphQL unterstützt das Zusammenfassen von Anfragen, dies ist auch bekannt als Query Batching. Query Batching ermöglicht es dem Client, mehrere Abfragen für mehrere Objektinstanzen in einem Aufruf zu bündeln. Dies ermöglicht einen sogenannten Batching Angriff. Dabei handelt es sich um eine Form eines Brute-Force-Angriffs. Um diese Art von Angriffe zu verhindern, sollte das Batching von sensiblen Objekten wie z. B. Benutzernamen, E-Mails, Kennwörter, OTPs, Sitzungs-Tokens usw. unterbunden werden. Auf diese Weise ist ein Angreifer gezwungen, die API wie eine REST-API anzugreifen und für jede Objektinstanz einen anderen Netzwerkaufruf zu tätigen. Zugleich sollte die Anzahl an Anfragen, welche gleichzeitig ausgeführt werden kann auch begrenzt werden.

Missbrauch von unsicheren Standardkonfigurationen

Ein Beispiel hierfür wäre der Ansatz sogenannter "versteckter" API-Endpunkte. Oftmals werden diese für Funktionen bereitgestellt, die nicht für die Allgemeinheit zugänglich sein sollen. Grundsätzlich sind solche Endpunkte keine gute Idee, sollten diese jedoch ohne entsprechende Autorisierung zugänglich sein ist es noch schlechter, besonders im GraphQL Umfeld.

Im Rahmen der Bemühungen, die Entwicklerfreundlichkeit zu steigern, ermöglicht GraphQL mit der sogenannten Introspektion, die in den meisten GraphQL-Implementierungen standardmäßig aktiviert ist, API-Clients die dynamische Abfrage von Informationen über das Schema, einschließlich der Dokumentation und der Typen für jede im Schema definierte Abfrage und Mutation. Diese wird auch von Entwicklungswerkzeugen wie der GraphiQL IDE verwendet, um das Schema dynamisch abzurufen. Wenn Introspektion möglich ist, kann ein Angreifer das GraphQL-Schema erhalten, um die gesamte Angriffsfläche der API besser zu verstehen.

Wenn man auf eine GraphQL-API stößt, besteht der erste Schritt normalerweise darin, eine Introspektionsabfrage auszuführen, um eine Kopie des Schemas zu erhalten. Das Schema hilft dabei, die Angriffsfläche der exponierten GraphQL-API zu verstehen.

Der sicherste und einfachste Ansatz ist es, Introspektion und GraphiQL systemweit zu deaktivieren. Zusätzlich sollte die eingebaute Funktion, die einen Hinweis zurückgibt, wenn ein Feldname, den der Anfragende angibt, einem existierenden Feld ähnlich (aber falsch) ist, deaktiviert werden. Des Weiteren sollten Fehlermeldungen die zurückgegeben werden alla Stack-Traces deaktiviert werden, somit wird verhindert, dass ein Angreifer wertvolle Informationen über das System gewinnen kann.

Fazit

In diesem Post haben wir uns mit der grundlegenden Funktionsweise und Sicherheitsanforderungen an GraphQL beschäftigt. Authentifizierung und Autorisierung sind die ersten Herausforderungen, die es zu bewältigen gilt. Darüber hinaus wurde gezeigt, wie gängige GraphQL bezogene Angriffsflächen reduziert werden können.

Quellen zum Üben

Um die beschriebenen Angriffsmöglichkeiten zu trainieren und in der Praxis zu sehen, gibt es nachfolgend einige Quellen.

Damn Vulnerable GraphQL Application

TryHackMe - GraphQL Room

Kontakt

Neugierig? Überzeugt? Interessiert?

Vereinbaren Sie ein unverbindliches Erstgespräch mit einem unserer Vertriebsmitarbeiter. Nutzen Sie den folgenden Link, um einen Termin auszuwählen: