diff --git a/src/network-services-pentesting/pentesting-web/graphql.md b/src/network-services-pentesting/pentesting-web/graphql.md index 2ab004b5a..c2a08e9ed 100644 --- a/src/network-services-pentesting/pentesting-web/graphql.md +++ b/src/network-services-pentesting/pentesting-web/graphql.md @@ -25,7 +25,7 @@ Aby zidentyfikować wystawione instancje GraphQL, zaleca się uwzględnienie kon Identyfikacja otwartych instancji GraphQL pozwala na zbadanie wspieranych zapytań. To jest kluczowe dla zrozumienia danych dostępnych przez punkt końcowy. System introspekcji GraphQL ułatwia to, szczegółowo opisując zapytania, które wspiera schemat. Aby uzyskać więcej informacji na ten temat, zapoznaj się z dokumentacją GraphQL na temat introspekcji: [**GraphQL: język zapytań dla API.**](https://graphql.org/learn/introspection/) -### Odcisk +### Odcisk palca Narzędzie [**graphw00f**](https://github.com/dolevf/graphw00f) jest w stanie wykryć, który silnik GraphQL jest używany na serwerze, a następnie wydrukować przydatne informacje dla audytora bezpieczeństwa. @@ -68,7 +68,7 @@ Interesujące jest, czy **błędy** będą **pokazywane**, ponieważ przyczynią **Enumerowanie schematu bazy danych za pomocą introspekcji** > [!NOTE] -> Jeśli introspekcja jest włączona, ale powyższe zapytanie nie działa, spróbuj usunąć dyrektywy `onOperation`, `onFragment` i `onField` z struktury zapytania. +> Jeśli introspekcja jest włączona, ale powyższe zapytanie nie działa, spróbuj usunąć dyrektywy `onOperation`, `onFragment` i `onField` ze struktury zapytania. ```bash #Full introspection query @@ -172,7 +172,7 @@ Jeśli introspekcja jest włączona, możesz użyć [**GraphQL Voyager**](https: Teraz, gdy wiemy, jakie informacje są zapisane w bazie danych, spróbujmy **wyodrębnić kilka wartości**. -W introspekcji możesz znaleźć **który obiekt możesz bezpośrednio zapytać** (ponieważ nie możesz zapytać obiektu tylko dlatego, że istnieje). Na poniższym obrazku możesz zobaczyć, że "_queryType_" nazywa się "_Query_", a jednym z pól obiektu "_Query_" jest "_flags_", który jest również typem obiektu. Dlatego możesz zapytać obiekt flagi. +W introspekcji możesz znaleźć **który obiekt możesz bezpośrednio zapytać** (ponieważ nie możesz zapytać obiektu tylko dlatego, że istnieje). Na poniższym obrazku możesz zobaczyć, że "_queryType_" nazywa się "_Query_", a jednym z pól obiektu "_Query_" jest "_flags_", które jest również typem obiektu. Dlatego możesz zapytać obiekt flagi. ![](<../../images/Screenshot from 2021-03-13 18-17-48.png>) @@ -206,7 +206,7 @@ Tak czy inaczej, już to wiedzieliśmy, w sekcji [Basic Enumeration](graphql.md# Jeśli przeczytasz obrazek dostarczony, gdy uruchomiłem to zapytanie, zobaczysz, że "_**user**_" miał **arg** "_**uid**_" typu _Int_. -Więc, wykonując lekką _**uid**_ bruteforce, odkryłem, że dla _**uid**=**1**_ pobrano nazwę użytkownika i hasło:\ +Więc, wykonując lekką _**uid**_ bruteforce, odkryłem, że w _**uid**=**1**_ odzyskano nazwę użytkownika i hasło:\ `query={user(uid:1){user,password}}` ![](<../../images/image (90).png>) @@ -225,7 +225,7 @@ Jeśli możesz wyszukiwać według typu ciągu, jak: `query={theusers(descriptio W tej konfiguracji, **baza danych** zawiera **osoby** i **filmy**. **Osoby** są identyfikowane przez swój **email** i **imię**; **filmy** przez swoją **nazwę** i **ocenę**. **Osoby** mogą być przyjaciółmi i również mieć filmy, co wskazuje na relacje w bazie danych. -Możesz **wyszukiwać** osoby **po** **imieniu** i uzyskać ich emaile: +Możesz **wyszukiwać** osoby **po** **imię** i uzyskać ich emaile: ```javascript { searchPerson(name: "John Doe") { @@ -353,7 +353,7 @@ Jak widać na zrzucie ekranu odpowiedzi, pierwsze i trzecie żądania zwróciły Coraz więcej **punktów końcowych graphql wyłącza introspekcję**. Jednak błędy, które graphql zgłasza, gdy otrzymuje nieoczekiwane żądanie, są wystarczające dla narzędzi takich jak [**clairvoyance**](https://github.com/nikitastupin/clairvoyance), aby odtworzyć większość schematu. -Co więcej, rozszerzenie Burp Suite [**GraphQuail**](https://github.com/forcesunseen/graphquail) **obserwuje żądania API GraphQL przechodzące przez Burp** i **buduje** wewnętrzny **schemat** GraphQL z każdym nowym zapytaniem, które widzi. Może również ujawniać schemat dla GraphiQL i Voyager. Rozszerzenie zwraca fałszywą odpowiedź, gdy otrzymuje zapytanie introspekcyjne. W rezultacie GraphQuail pokazuje wszystkie zapytania, argumenty i pola dostępne do użycia w API. Więcej informacji [**sprawdź to**](https://blog.forcesunseen.com/graphql-security-testing-without-a-schema). +Ponadto rozszerzenie Burp Suite [**GraphQuail**](https://github.com/forcesunseen/graphquail) **obserwuje żądania API GraphQL przechodzące przez Burp** i **buduje** wewnętrzny **schemat** GraphQL z każdym nowym zapytaniem, które widzi. Może również ujawniać schemat dla GraphiQL i Voyager. Rozszerzenie zwraca fałszywą odpowiedź, gdy otrzymuje zapytanie introspekcyjne. W rezultacie GraphQuail pokazuje wszystkie zapytania, argumenty i pola dostępne do użycia w API. Więcej informacji [**sprawdź to**](https://blog.forcesunseen.com/graphql-security-testing-without-a-schema). Ładna **lista słów** do odkrywania [**jednostek GraphQL można znaleźć tutaj**](https://github.com/Escape-Technologies/graphql-wordlist?). @@ -395,9 +395,9 @@ payload: GQL_CALL, ws.send(JSON.stringify(graphqlMsg)) } ``` -### **Odkrywanie Ujawnionych Struktur GraphQL** +### **Odkrywanie Odkrytych Struktur GraphQL** -Gdy introspekcja jest wyłączona, badanie kodu źródłowego strony internetowej w poszukiwaniu wstępnie załadowanych zapytań w bibliotekach JavaScript jest przydatną strategią. Te zapytania można znaleźć, korzystając z zakładki `Sources` w narzędziach deweloperskich, co daje wgląd w schemat API i ujawnia potencjalnie **ujawnione wrażliwe zapytania**. Polecenia do wyszukiwania w narzędziach deweloperskich to: +Gdy introspekcja jest wyłączona, badanie kodu źródłowego strony internetowej w poszukiwaniu wstępnie załadowanych zapytań w bibliotekach JavaScript jest przydatną strategią. Te zapytania można znaleźć, korzystając z zakładki `Sources` w narzędziach deweloperskich, co daje wgląd w schemat API i ujawnia potencjalnie **odkryte wrażliwe zapytania**. Polecenia do wyszukiwania w narzędziach deweloperskich to: ```javascript Inspect/Sources/"Search all files" file:* mutation @@ -421,13 +421,13 @@ Jednak większość punktów końcowych GraphQL obsługuje również **`form-url ```javascript query=%7B%0A++user+%7B%0A++++firstName%0A++++__typename%0A++%7D%0A%7D%0A ``` -Dlatego, ponieważ żądania CSRF, takie jak poprzednie, są wysyłane **bez żądań preflight**, możliwe jest **wprowadzenie** **zmian** w GraphQL, wykorzystując CSRF. +Zatem, ponieważ żądania CSRF, takie jak poprzednie, są wysyłane **bez żądań preflight**, możliwe jest **wprowadzenie** **zmian** w GraphQL, wykorzystując CSRF. Należy jednak zauważyć, że nowa domyślna wartość ciasteczka flagi `samesite` w Chrome to `Lax`. Oznacza to, że ciasteczko będzie wysyłane tylko z zewnętrznej strony w żądaniach GET. Należy pamiętać, że zazwyczaj możliwe jest również wysłanie **żądania** **zapytania** jako **żądania GET**, a token CSRF może nie być weryfikowany w żądaniu GET. -Ponadto, wykorzystując atak [**XS-Search**](../../pentesting-web/xs-search/index.html), może być możliwe wyeksportowanie treści z punktu końcowego GraphQL, wykorzystując dane uwierzytelniające użytkownika. +Ponadto, wykorzystując atak [**XS-Search**](../../pentesting-web/xs-search/index.html), może być możliwe wykradzenie treści z punktu końcowego GraphQL, wykorzystując dane uwierzytelniające użytkownika. Aby uzyskać więcej informacji, **sprawdź** [**oryginalny post tutaj**](https://blog.doyensec.com/2021/05/20/graphql-csrf.html). @@ -465,7 +465,7 @@ W poniższym przykładzie widać, że operacja to "forgotPassword" i powinna ona ## Ominięcie limitów szybkości przy użyciu aliasów w GraphQL -W GraphQL aliasy to potężna funkcja, która pozwala na **jawne nazywanie właściwości** podczas składania żądania API. Ta możliwość jest szczególnie przydatna do pobierania **wielu instancji tego samego typu** obiektu w jednym żądaniu. Aliasy mogą być używane do pokonywania ograniczenia, które uniemożliwia obiektom GraphQL posiadanie wielu właściwości o tej samej nazwie. +W GraphQL aliasy to potężna funkcja, która pozwala na **jawne nazywanie właściwości** podczas składania żądania API. Ta możliwość jest szczególnie przydatna do pobierania **wielu instancji tego samego typu** obiektu w jednym żądaniu. Aliasów można używać, aby przezwyciężyć ograniczenie, które uniemożliwia obiektom GraphQL posiadanie wielu właściwości o tej samej nazwie. Aby uzyskać szczegółowe zrozumienie aliasów GraphQL, zaleca się następujące źródło: [Aliases](https://portswigger.net/web-security/graphql/what-is-graphql#aliases). @@ -490,18 +490,18 @@ valid ### Przeciążenie aliasów -**Przeciążenie aliasów** to luka w GraphQL, w której atakujący przeciążają zapytanie wieloma aliasami dla tego samego pola, co powoduje, że resolver backendu wykonuje to pole wielokrotnie. Może to przytłoczyć zasoby serwera, prowadząc do **Denial of Service (DoS)**. Na przykład, w poniższym zapytaniu to samo pole (`expensiveField`) jest żądane 1,000 razy przy użyciu aliasów, zmuszając backend do obliczenia go 1,000 razy, co potencjalnie może wyczerpać CPU lub pamięć: +**Przeciążenie aliasów** to luka w GraphQL, w której atakujący przeciążają zapytanie wieloma aliasami dla tego samego pola, co powoduje, że resolver backendu wykonuje to pole wielokrotnie. Może to przytłoczyć zasoby serwera, prowadząc do **odmowy usługi (DoS)**. Na przykład, w poniższym zapytaniu to samo pole (`expensiveField`) jest żądane 1,000 razy za pomocą aliasów, zmuszając backend do obliczenia go 1,000 razy, co potencjalnie wyczerpuje CPU lub pamięć: ```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' ``` -Aby to złagodzić, wdroż ograniczenia liczby aliasów, analizę złożoności zapytań lub ograniczenia szybkości, aby zapobiec nadużywaniu zasobów. +Aby temu zapobiec, wdroż ograniczenia liczby aliasów, analizę złożoności zapytań lub ograniczenia szybkości, aby zapobiec nadużywaniu zasobów. ### **Batched Query na bazie tablicy** -**Batched Query na bazie tablicy** to luka, w której API GraphQL pozwala na grupowanie wielu zapytań w jednym żądaniu, umożliwiając atakującemu wysłanie dużej liczby zapytań jednocześnie. Może to przytłoczyć backend, wykonując wszystkie zgrupowane zapytania równolegle, zużywając nadmierne zasoby (CPU, pamięć, połączenia z bazą danych) i potencjalnie prowadząc do **Denial of Service (DoS)**. Jeśli nie ma ograniczenia liczby zapytań w partii, atakujący może to wykorzystać do pogorszenia dostępności usługi. +**Batched Query na bazie tablicy** to luka, w której API GraphQL pozwala na grupowanie wielu zapytań w jednym żądaniu, co umożliwia atakującemu wysłanie dużej liczby zapytań jednocześnie. Może to przytłoczyć backend, wykonując wszystkie zgrupowane zapytania równolegle, co prowadzi do nadmiernego zużycia zasobów (CPU, pamięć, połączenia z bazą danych) i potencjalnie prowadzi do **Denial of Service (DoS)**. Jeśli nie ma ograniczenia liczby zapytań w partii, atakujący może to wykorzystać do pogorszenia dostępności usługi. ```graphql # Test provided by https://github.com/dolevf/graphql-cop curl -X POST -H "User-Agent: graphql-cop/1.13" \ @@ -550,7 +550,7 @@ curl -X POST -H "User-Agent: graphql-cop/1.13" -H "Content-Type: application/jso ### Skanery podatności -- [https://github.com/dolevf/graphql-cop](https://github.com/dolevf/graphql-cop): Testuje powszechne błędy w konfiguracji punktów końcowych GraphQL +- [https://github.com/dolevf/graphql-cop](https://github.com/dolevf/graphql-cop): Testuje powszechne błędy konfiguracji punktów końcowych GraphQL - [https://github.com/assetnote/batchql](https://github.com/assetnote/batchql): Skrypt audytujący bezpieczeństwo GraphQL z naciskiem na wykonywanie zbiorczych zapytań i mutacji GraphQL. - [https://github.com/dolevf/graphw00f](https://github.com/dolevf/graphw00f): Identyfikuje używaną wersję GraphQL - [https://github.com/gsmith257-cyber/GraphCrawler](https://github.com/gsmith257-cyber/GraphCrawler): Zestaw narzędzi, który można wykorzystać do pobierania schematów i wyszukiwania danych wrażliwych, testowania autoryzacji, ataków brute force na schematy oraz znajdowania ścieżek do danego typu. @@ -561,6 +561,10 @@ curl -X POST -H "User-Agent: graphql-cop/1.13" -H "Content-Type: application/jso - [https://github.com/doyensec/inql](https://github.com/doyensec/inql): Rozszerzenie Burp lub skrypt Pythona do zaawansowanego testowania GraphQL. _**Skaner**_ jest rdzeniem InQL v5.0, gdzie można analizować punkt końcowy GraphQL lub lokalny plik schematu introspekcji. Automatycznie generuje wszystkie możliwe zapytania i mutacje, organizując je w uporządkowany widok do analizy. Komponent _**Atakujący**_ pozwala na przeprowadzanie zbiorczych ataków GraphQL, co może być przydatne do omijania źle zaimplementowanych limitów: `python3 inql.py -t http://example.com/graphql -o output.json` - [https://github.com/nikitastupin/clairvoyance](https://github.com/nikitastupin/clairvoyance): Próbuje uzyskać schemat nawet przy wyłączonej introspekcji, korzystając z pomocy niektórych baz danych GraphQL, które zasugerują nazwy mutacji i parametrów. +### Skrypty do wykorzystywania powszechnych podatności + +- [https://github.com/reycotallo98/pentestScripts/tree/main/GraphQLDoS](https://github.com/reycotallo98/pentestScripts/tree/main/GraphQLDoS): Zbiór skryptów do wykorzystywania podatności na ataki typu denial-of-service w podatnych środowiskach GraphQL. + ### Klienci - [https://github.com/graphql/graphiql](https://github.com/graphql/graphiql): Klient GUI