<summary><strong>Erlernen Sie AWS-Hacking von Null auf Held mit</strong><ahref="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
* Wenn Sie Ihr **Unternehmen in HackTricks beworben sehen möchten** oder **HackTricks als PDF herunterladen möchten**, überprüfen Sie die [**ABONNEMENTPLÄNE**](https://github.com/sponsors/carlospolop)!
* Holen Sie sich das [**offizielle PEASS & HackTricks-Merchandise**](https://peass.creator-spring.com)
* **Treten Sie der** 💬 [**Discord-Gruppe**](https://discord.gg/hRep4RUj7f) oder der [**Telegram-Gruppe**](https://t.me/peass) bei oder **folgen** Sie uns auf **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
* **Teilen Sie Ihre Hacking-Tricks, indem Sie PRs an die** [**HackTricks**](https://github.com/carlospolop/hacktricks) und [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) GitHub-Repositorys einreichen.
GraphQL wird als **effiziente Alternative** zu REST-APIs hervorgehoben und bietet einen vereinfachten Ansatz zum Abfragen von Daten vom Backend. Im Gegensatz zu REST, bei dem oft zahlreiche Anfragen an verschiedene Endpunkte gestellt werden müssen, um Daten zu sammeln, ermöglicht GraphQL das Abrufen aller erforderlichen Informationen durch eine **einzige Anfrage**. Diese Vereinfachung **nutzt Entwicklern** erheblich, indem sie die Komplexität ihrer Datenabrufprozesse verringert.
Mit dem Aufkommen neuer Technologien, einschließlich GraphQL, entstehen auch neue Sicherheitslücken. Ein wichtiger Punkt ist, dass **GraphQL standardmäßig keine Authentifizierungsmechanismen enthält**. Es liegt in der Verantwortung der Entwickler, solche Sicherheitsmaßnahmen zu implementieren. Ohne ordnungsgemäße Authentifizierung können GraphQL-Endpunkte sensible Informationen für nicht authentifizierte Benutzer freigeben und ein erhebliches Sicherheitsrisiko darstellen.
Um freiliegende GraphQL-Instanzen zu identifizieren, wird die Einbeziehung spezifischer Pfade in Verzeichnis-Brute-Force-Angriffen empfohlen. Diese Pfade sind:
Die Identifizierung offener GraphQL-Instanzen ermöglicht die Untersuchung unterstützter Abfragen. Dies ist entscheidend, um die über den Endpunkt zugänglichen Daten zu verstehen. Das Introspektionsystem von GraphQL erleichtert dies, indem es die Abfragen detailliert auflistet, die ein Schema unterstützt. Für weitere Informationen hierzu siehe die GraphQL-Dokumentation zur Introspektion: [**GraphQL: Eine Abfragesprache für APIs.**](https://graphql.org/learn/introspection/)
Das Tool [**graphw00f**](https://github.com/dolevf/graphw00f) ist in der Lage zu erkennen, welcher GraphQL-Engine auf einem Server verwendet wird, und liefert dann einige hilfreiche Informationen für den Sicherheitsprüfer.
Um zu überprüfen, ob eine URL ein GraphQL-Dienst ist, kann eine **universelle Abfrage**, `query{__typename}`, gesendet werden. Wenn die Antwort `{"data": {"__typename": "Query"}}` enthält, bestätigt dies, dass die URL einen GraphQL-Endpunkt hostet. Diese Methode basiert auf dem Feld `__typename` von GraphQL, das den Typ des abgefragten Objekts offenbart.
Graphql unterstützt in der Regel **GET**, **POST** (x-www-form-urlencoded) und **POST**(json). Obwohl es aus Sicherheitsgründen empfohlen wird, nur json zuzulassen, um CSRF-Angriffe zu verhindern.
Um die Schema-Informationen mit Hilfe der Introspektion zu entdecken, frage das `__schema`-Feld ab. Dieses Feld ist auf dem Wurzeltyp aller Abfragen verfügbar.
Mit dieser Abfrage können Sie alle Typen, deren Felder und Argumente (und den Typ der Argumente) extrahieren. Dies wird sehr nützlich sein, um zu wissen, wie die Datenbank abgefragt werden kann.
Wenn die Introspektion aktiviert ist, aber die obige Abfrage nicht ausgeführt wird, versuchen Sie, die Direktiven `onOperation`, `onFragment` und `onField` aus der Abfragestruktur zu entfernen.
Wenn die Introspektion aktiviert ist, können Sie [**GraphQL Voyager**](https://github.com/APIs-guru/graphql-voyager) verwenden, um alle Optionen in einer GUI anzuzeigen.
In der Introspektion können Sie herausfinden, **welches Objekt Sie direkt abfragen können** (weil Sie ein Objekt nicht abfragen können, nur weil es existiert). Im folgenden Bild sehen Sie, dass der "_queryType_" "_Query_" genannt wird und dass eines der Felder des "_Query_"-Objekts "_flags_" ist, das auch ein Objekttyp ist. Daher können Sie das Flag-Objekt abfragen.
Sie können sehen, dass die "_Flags_"-Objekte aus **Name** und **Wert** bestehen. Dann können Sie alle Namen und Werte der Flags mit der Abfrage erhalten:
Wenn diese Objekte keine Argumente zum Suchen benötigen, könnten Sie **alle Informationen von ihnen abrufen**, indem Sie einfach nach den Daten fragen, die Sie möchten. In diesem Beispiel aus dem Internet könnten Sie Benutzernamen und Passwörter extrahieren:
Es scheint, dass auf irgendeine Weise nach dem "_**uid**_"-Argument vom Typ _**Int**_ gesucht wird.\
Wie auch immer, wir wussten bereits, dass in der [Grundlegenden Aufzählung](graphql.md#basic-enumeration) ein Abfrage vorgeschlagen wurde, die uns alle benötigten Informationen zeigte: `query={__schema{types{name,fields{name, args{name,description,type{name, kind, ofType{name, kind}}}}}}}`
Wenn Sie das bereitgestellte Bild lesen, wenn ich diese Abfrage ausführe, werden Sie sehen, dass "_**user**_" das **Arg** "_**uid**_" vom Typ _Int_ hatte.
Daher habe ich durch Ausführung eines leichten _**uid**_-Brute-Force herausgefunden, dass bei _**uid**=**1**_ ein Benutzername und ein Passwort abgerufen wurden:\
Beachten Sie, dass ich **festgestellt** habe, dass ich nach den **Parametern** "_**user**_" und "_**password**_" fragen konnte, denn wenn ich nach etwas suche, das nicht existiert (`query={user(uid:1){noExists}}`), erhalte ich diesen Fehler:
Wenn Sie nach einem String-Typ suchen können, wie: `query={theusers(description: ""){username,password}}` und Sie nach einem leeren String suchen, werden alle Daten **ausgegeben**. (_Beachten Sie, dass dieses Beispiel nicht mit dem Beispiel der Tutorials zusammenhängt. Für dieses Beispiel nehmen Sie an, dass Sie mit "**theusers**" nach einem String-Feld namens "**description**" suchen können"_).
In dieser Konfiguration enthält eine **Datenbank****Personen** und **Filme**. **Personen** werden anhand ihrer **E-Mail** und ihres **Namens** identifiziert; **Filme** anhand ihres **Namens** und ihrer **Bewertung**. **Personen** können miteinander befreundet sein und auch Filme haben, was Beziehungen innerhalb der Datenbank anzeigt.
In der **Introspektion** können Sie die **deklarierten****Mutationen** finden. Im folgenden Bild wird der "_MutationType_" als "_Mutation_" bezeichnet und das "_Mutation_"-Objekt enthält die Namen der Mutationen (wie "_addPerson_" in diesem Fall):
In diesem Setup enthält eine **Datenbank****Personen** und **Filme**. **Personen** werden anhand ihrer **E-Mail** und ihres **Namens** identifiziert; **Filme** anhand ihres **Namens** und ihrer **Bewertung**. **Personen** können miteinander befreundet sein und auch Filme haben, was Beziehungen innerhalb der Datenbank anzeigt.
Zusätzlich unterstützt die Datenbank eine **Mutation**-Operation namens `addPerson`, die die Erstellung von **Personen** zusammen mit ihren Verknüpfungen zu vorhandenen **Freunden** und **Filmen** ermöglicht. Es ist entscheidend zu beachten, dass die Freunde und Filme vor dem Verknüpfen mit der neu erstellten Person bereits in der Datenbank vorhanden sein müssen.
Wie in [**einer der Schwachstellen, die in diesem Bericht beschrieben sind**](https://www.landh.tech/blog/20240304-google-hack-50000/) erläutert, bedeutet eine Direktivenüberlastung, eine Direktive sogar Millionen von Malen aufzurufen, um den Server dazu zu bringen, Operationen zu verschwenden, bis es möglich ist, einen DoS-Angriff durchzuführen.
Authentifizierung über GraphQL-API durch **gleichzeitiges Senden vieler Abfragen mit unterschiedlichen Anmeldeinformationen**, um sie zu überprüfen. Es handelt sich um einen klassischen Brute-Force-Angriff, aber jetzt ist es möglich, mehr als ein Login/Passwort-Paar pro HTTP-Anfrage zu senden, aufgrund der GraphQL-Batching-Funktion. Dieser Ansatz würde externe Rate-Monitoring-Anwendungen dazu bringen zu glauben, dass alles in Ordnung ist und es keinen Brute-Force-Bot gibt, der versucht, Passwörter zu erraten.
Im Folgenden finden Sie die einfachste Demonstration einer Authentifizierungsanfrage der Anwendung, mit **3 verschiedenen E-Mail/Passwort-Paaren gleichzeitig**. Offensichtlich ist es möglich, auf die gleiche Weise Tausende in einer einzigen Anfrage zu senden:
Wie aus dem Antwort-Screenshot ersichtlich ist, haben die ersten und dritten Anfragen _null_ zurückgegeben und die entsprechenden Informationen im _error_-Abschnitt reflektiert. Die **zweite Mutation enthielt die korrekten Authentifizierungsdaten** und die Antwort enthielt das korrekte Authentifizierungssitzungstoken.
Immer mehr **GraphQL-Endpunkte deaktivieren die Introspektion**. Die Fehler, die GraphQL wirft, wenn eine unerwartete Anfrage empfangen wird, reichen jedoch aus, damit Tools wie [**clairvoyance**](https://github.com/nikitastupin/clairvoyance) den Großteil des Schemas rekonstruieren können.
Darüber hinaus beobachtet die Burp Suite-Erweiterung [**GraphQuail**](https://github.com/forcesunseen/graphquail) **GraphQL-API-Anfragen, die durch Burp gehen** und **erstellt** ein internes GraphQL-**Schema** mit jeder neuen Abfrage, die es sieht. Es kann auch das Schema für GraphiQL und Voyager freigeben. Die Erweiterung gibt eine gefälschte Antwort zurück, wenn sie eine Introspektionsabfrage erhält. Als Ergebnis zeigt GraphQuail alle Abfragen, Argumente und Felder, die innerhalb der API verwendet werden können. Weitere Informationen finden Sie [**hier**](https://blog.forcesunseen.com/graphql-security-testing-without-a-schema).
Um Beschränkungen bei Introspektionsabfragen in APIs zu umgehen, erweist sich das Einfügen eines **Sonderzeichens nach dem `__schema`-Schlüsselwort** als wirksam. Diese Methode nutzt häufige Entwicklerfehler in Regex-Mustern aus, die darauf abzielen, die Introspektion durch Fokussierung auf das `__schema`-Schlüsselwort zu blockieren. Durch das Hinzufügen von Zeichen wie **Leerzeichen, Zeilenumbrüche und Kommas**, die von GraphQL ignoriert werden, aber möglicherweise nicht in Regex berücksichtigt werden, können Beschränkungen umgangen werden. Beispielsweise kann eine Introspektionsabfrage mit einem Zeilenumbruch nach `__schema` solche Abwehrmaßnahmen umgehen:
Wenn dies nicht erfolgreich ist, sollten alternative Anfragemethoden in Betracht gezogen werden, wie z.B. **GET-Anfragen** oder **POST mit `x-www-form-urlencoded`**, da Einschränkungen möglicherweise nur für POST-Anfragen gelten.
Wenn die Introspektion deaktiviert ist, ist die Untersuchung des Quellcodes der Website nach vorab geladenen Abfragen in JavaScript-Bibliotheken eine nützliche Strategie. Diese Abfragen können mithilfe des `Quellen`-Tabs in den Entwicklertools gefunden werden und Einblicke in das API-Schema bieten sowie potenziell **sensible freigelegte Abfragen** aufdecken. Die Befehle zum Suchen in den Entwicklertools lauten:
Beachten Sie jedoch, dass der neue Standard-Cookie-Wert des `samesite`-Flags von Chrome `Lax` ist. Dies bedeutet, dass das Cookie nur von einer Drittanbieter-Website in GET-Anfragen gesendet wird.
Es ist in der Regel möglich, die **Abfrageanfrage** auch als **GET**-Anfrage zu senden, und das CSRF-Token wird möglicherweise nicht in einer GET-Anfrage validiert.
Durch die Ausnutzung eines [**XS-Search**](../../pentesting-web/xs-search/)-**Angriffs** könnte es möglich sein, Inhalte aus dem GraphQL-Endpunkt unter Ausnutzung der Anmeldeinformationen des Benutzers zu exfiltrieren.
Viele in dem Endpunkt definierte GraphQL-Funktionen überprüfen möglicherweise nur die Authentifizierung des Anfragenden, jedoch nicht die Autorisierung.
Das [Verketten von Abfragen](https://s1n1st3r.gitbook.io/theb10g/graphql-query-authentication-bypass-vuln) kann ein schwaches Authentifizierungssystem umgehen.
Im folgenden Beispiel sehen Sie, dass die Operation "forgotPassword" ist und dass nur die damit verbundene forgotPassword-Abfrage ausgeführt werden sollte. Dies kann umgangen werden, indem am Ende eine weitere Abfrage hinzugefügt wird. In diesem Fall fügen wir "register" und eine Benutzervariable hinzu, damit das System sich als neuer Benutzer registrieren kann.
In GraphQL sind Aliasse ein leistungsstarkes Feature, das es ermöglicht, **Eigenschaften explizit zu benennen**, wenn eine API-Anfrage gestellt wird. Diese Funktion ist besonders nützlich, um **mehrere Instanzen desselben Objekttyps** innerhalb einer einzelnen Anfrage abzurufen. Aliasse können eingesetzt werden, um die Einschränkung zu überwinden, die verhindert, dass GraphQL-Objekte mehrere Eigenschaften mit demselben Namen haben.
Für ein detailliertes Verständnis von GraphQL-Aliassen wird die folgende Ressource empfohlen: [Aliasse](https://portswigger.net/web-security/graphql/what-is-graphql#aliases).
Während der Hauptzweck von Aliassen darin besteht, die Notwendigkeit für zahlreiche API-Aufrufe zu reduzieren, wurde ein unbeabsichtigter Anwendungsfall identifiziert, bei dem Aliasse genutzt werden können, um Brute-Force-Angriffe auf einen GraphQL-Endpunkt auszuführen. Dies ist möglich, da einige Endpunkte durch Rate-Limiter geschützt sind, die darauf ausgelegt sind, Brute-Force-Angriffe zu vereiteln, indem sie die **Anzahl der HTTP-Anfragen** beschränken. Diese Rate-Limiter berücksichtigen jedoch möglicherweise nicht die Anzahl der Operationen innerhalb jeder Anfrage. Da Aliasse das Einbeziehen mehrerer Abfragen in einer einzelnen HTTP-Anfrage ermöglichen, können sie solche Rate-Limiting-Maßnahmen umgehen.
Betrachten Sie das untenstehende Beispiel, das veranschaulicht, wie aliased Abfragen verwendet werden können, um die Gültigkeit von Rabattcodes im Geschäft zu überprüfen. Diese Methode könnte die Umgehung von Rate Limits ermöglichen, da sie mehrere Abfragen in einer HTTP-Anfrage zusammenfasst und somit die Überprüfung zahlreicher Rabattcodes gleichzeitig ermöglicht.
* [https://github.com/assetnote/batchql](https://github.com/assetnote/batchql): Skript zur Überprüfung der GraphQL-Sicherheit mit Schwerpunkt auf der Durchführung von Batch-GraphQL-Abfragen und -Mutationen.
* [https://github.com/dolevf/graphw00f](https://github.com/dolevf/graphw00f): Erkennt die verwendete GraphQL-Version
* [https://github.com/gsmith257-cyber/GraphCrawler](https://github.com/gsmith257-cyber/GraphCrawler): Toolkit, das zum Abrufen von Schemas und zum Suchen nach sensiblen Daten, zum Testen von Autorisierungen, zum Brute-Forcing von Schemas und zum Finden von Pfaden zu einem bestimmten Typ verwendet werden kann.
* [https://blog.doyensec.com/2020/03/26/graphql-scanner.html](https://blog.doyensec.com/2020/03/26/graphql-scanner.html): Kann eigenständig oder als [Burp-Erweiterung](https://github.com/doyensec/inql) verwendet werden.
* [https://github.com/swisskyrepo/GraphQLmap](https://github.com/swisskyrepo/GraphQLmap): Kann auch als CLI-Client verwendet werden, um Angriffe zu automatisieren
* [https://gitlab.com/dee-see/graphql-path-enum](https://gitlab.com/dee-see/graphql-path-enum): Tool, das die verschiedenen Möglichkeiten auflistet, einen bestimmten Typ in einem GraphQL-Schema zu erreichen.
* [https://github.com/doyensec/inql](https://github.com/doyensec/inql): Burp-Erweiterung für fortgeschrittenes GraphQL-Testing. Der _**Scanner**_ ist der Kern von InQL v5.0, mit dem Sie einen GraphQL-Endpunkt oder eine lokale Introspektions-Schema-Datei analysieren können. Er generiert automatisch alle möglichen Abfragen und Mutationen und organisiert sie in einer strukturierten Ansicht für Ihre Analyse. Das _**Attacker**_-Modul ermöglicht das Ausführen von Batch-GraphQL-Angriffen, was nützlich sein kann, um schlecht implementierte Rate-Limits zu umgehen.
<summary><strong>Erlernen Sie AWS-Hacking von Grund auf mit</strong><ahref="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
* Wenn Sie Ihr **Unternehmen in HackTricks bewerben möchten** oder **HackTricks als PDF herunterladen möchten**, überprüfen Sie die [**ABONNEMENTPLÄNE**](https://github.com/sponsors/carlospolop)!
* **Treten Sie der** 💬 [**Discord-Gruppe**](https://discord.gg/hRep4RUj7f) oder der [**Telegram-Gruppe**](https://t.me/peass) bei oder **folgen** Sie uns auf **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
* **Teilen Sie Ihre Hacking-Tricks, indem Sie PRs an die** [**HackTricks**](https://github.com/carlospolop/hacktricks) und [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) GitHub-Repositories senden.