mirror of
				https://github.com/HackTricks-wiki/hacktricks.git
				synced 2025-10-10 18:36:50 +00:00 
			
		
		
		
	Translated ['src/network-services-pentesting/pentesting-web/graphql.md']
This commit is contained in:
		
							parent
							
								
									3365aaaed2
								
							
						
					
					
						commit
						f50d04c42b
					
				@ -23,7 +23,7 @@ Da bi se identifikovale izložene GraphQL instance, preporučuje se uključivanj
 | 
				
			|||||||
- `/graphql/api`
 | 
					- `/graphql/api`
 | 
				
			||||||
- `/graphql/graphql`
 | 
					- `/graphql/graphql`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Identifikacija otvorenih GraphQL instanci omogućava ispitivanje podržanih upita. Ovo je ključno za razumevanje podataka dostupnih preko 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/)
 | 
					Identifikacija otvorenih GraphQL instanci omogućava ispitivanje podržanih upita. Ovo je ključno za razumevanje podataka dostupnih preko krajnje tačke. GraphQL-ov introspekcijski sistem olakšava ovo detaljno prikazujući upite koje šema podržava. Za više informacija o tome, pogledajte GraphQL dokumentaciju o introspekciji: [**GraphQL: Jezik upita za API-e.**](https://graphql.org/learn/introspection/)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Otisak
 | 
					### Otisak
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -31,7 +31,7 @@ Alat [**graphw00f**](https://github.com/dolevf/graphw00f) je sposoban da detektu
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#### Univerzalni upiti <a href="#universal-queries" id="universal-queries"></a>
 | 
					#### Univerzalni upiti <a href="#universal-queries" id="universal-queries"></a>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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.
 | 
					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 upitog objekta.
 | 
				
			||||||
```javascript
 | 
					```javascript
 | 
				
			||||||
query{__typename}
 | 
					query{__typename}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
@ -51,13 +51,13 @@ Sa ovom upitom ćete pronaći imena svih tipova koji se koriste:
 | 
				
			|||||||
```bash
 | 
					```bash
 | 
				
			||||||
query={__schema{types{name,fields{name,args{name,description,type{name,kind,ofType{name, kind}}}}}}}
 | 
					query={__schema{types{name,fields{name,args{name,description,type{name,kind,ofType{name, kind}}}}}}}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
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.
 | 
					Sa ovom upitom možete izvući sve tipove, njihova polja i njihove argumente (kao i tip argumenata). Ovo će biti veoma korisno za razumevanje kako da upitujete bazu podataka.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.png>)
 | 
					.png>)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
**Greške**
 | 
					**Greške**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Zanimljivo je znati da li će se **greške** prikazivati jer će doprineti korisnim **informacijama.**
 | 
					Zanimljivo je znati da li će se **greške** **prikazivati** jer će doprineti korisnim **informacijama.**
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
?query={__schema}
 | 
					?query={__schema}
 | 
				
			||||||
?query={}
 | 
					?query={}
 | 
				
			||||||
@ -158,15 +158,15 @@ name
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
Инлајн интроспекција упит:
 | 
					Inline introspection upit:
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
/?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}+}
 | 
					/?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-a (imena objekata, parametre, tipove...)
 | 
					Poslednja linija koda je graphql upit koji će izbaciti sve meta-informacije iz graphql (imena objekata, parametre, tipove...)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.png>)
 | 
					.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.
 | 
					Ako je introspekcija omogućena, možete koristiti [**GraphQL Voyager**](https://github.com/APIs-guru/graphql-voyager) da u GUI-ju vidite sve opcije.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Upit
 | 
					### Upit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -201,17 +201,17 @@ Međutim, u ovom primeru, ako pokušate to da uradite, dobijate ovu **grešku**:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
.png>)
 | 
					.png>)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Izgleda da će nekako pretraživati koristeći argument "_**uid**_" tipa _**Int**_.\
 | 
					Izgleda da će na neki način pretraživati koristeći argument "_**uid**_" tipa _**Int**_.\
 | 
				
			||||||
U svakom slučaju, već smo to znali, u sekciji [Basic Enumeration](graphql.md#basic-enumeration) predložen je upit koji nam je pokazivao sve potrebne informacije: `query={__schema{types{name,fields{name, args{name,description,type{name, kind, ofType{name, kind}}}}}}}`
 | 
					U svakom slučaju, već smo to znali, u sekciji [Basic Enumeration](graphql.md#basic-enumeration) predložen je 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_.
 | 
					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**_ dobijeno korisničko ime i lozinka:\
 | 
					Dakle, vršeći lagani _**uid**_ bruteforce, otkrio sam da je za _**uid**=**1**_ dobijeno korisničko ime i lozinka:\
 | 
				
			||||||
`query={user(uid:1){user,password}}`
 | 
					`query={user(uid:1){user,password}}`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.png>)
 | 
					.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:
 | 
					Napomena da sam **otkrio** da mogu tražiti **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:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.png>)
 | 
					.png>)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -219,13 +219,13 @@ I tokom **faze enumeracije** otkrio sam da objekat "_**dbuser**_" ima kao polja
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
**Trik sa dump-ovanjem upitnog stringa (zahvaljujući @BinaryShadow\_)**
 | 
					**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 praznu string** dobićete **dump svih podataka**. (_Napomena: ovaj primer nije povezan sa primerom iz tutorijala, za ovaj primer pretpostavite da možete pretraživati koristeći "**theusers**" po String polju nazvanom "**description**"_).
 | 
					Ako možete pretraživati po string tipu, kao: `query={theusers(description: ""){username,password}}` i **tražite prazni string**, to će **dump-ovati sve podatke**. (_Napomena: ovaj primer nije povezan sa primerom iz tutorijala, za ovaj primer pretpostavite da možete pretraživati koristeći "**theusers**" po String polju nazvanom "**description**"_).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Pretraga
 | 
					### Pretraga
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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.
 | 
					U ovom podešavanju, **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.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Možete **pretraživati** osobe **po** **imenu** i dobiti njihove email adrese:
 | 
					Možete **pretraživati** osobe **po** **imenu** i dobiti njihove emailove:
 | 
				
			||||||
```javascript
 | 
					```javascript
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
searchPerson(name: "John Doe") {
 | 
					searchPerson(name: "John Doe") {
 | 
				
			||||||
@ -334,12 +334,12 @@ releaseYear
 | 
				
			|||||||
```
 | 
					```
 | 
				
			||||||
### Direktiva Preopterećenja
 | 
					### 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 resurse dok nije moguće izvršiti DoS napad.
 | 
					Kao što je objašnjeno u [**jednoj od ranjivosti opisane 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 resurse dok nije moguće izvršiti DoS napad.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Grupisanje brute-force u 1 API zahtevu
 | 
					### 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/).\
 | 
					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 više upita sa različitim akreditivima** kako 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 funkcije grupisanja. Ovaj pristup bi prevario spoljne aplikacije za praćenje brzine misleći da je sve u redu i da ne postoji bot koji pokušava da pogodi lozinke.
 | 
					Autentifikacija putem GraphQL API sa **istovremenim slanjem više upita sa različitim akreditivima** kako 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 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:
 | 
					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:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -357,7 +357,7 @@ Sve više **graphql krajnjih tačaka onemogućava introspekciju**. Međutim, gre
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
Lepa **lista reči** za otkrivanje [**GraphQL entiteta može se pronaći ovde**](https://github.com/Escape-Technologies/graphql-wordlist?).
 | 
					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 <a href="#bypassing-graphql-introspection-defences" id="bypassing-graphql-introspection-defences"></a>
 | 
					### Zaobilaženje odbrana GraphQL introspekcije <a href="#bypassing-graphql-introspection-defences" id="bypassing-graphql-introspection-defences"></a>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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:
 | 
					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
 | 
					```bash
 | 
				
			||||||
@ -371,7 +371,7 @@ Ako ne uspete, razmotrite alternativne metode zahteva, kao što su **GET zahtevi
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
### Pokušajte sa WebSockets
 | 
					### 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 na graphQL putem WebSockets, jer bi to moglo omogućiti da zaobiđete potencijalni WAF i da komunikacija putem websocket-a otkrije šemu graphQL-a:
 | 
					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 na graphQL putem WebSockets, jer bi to moglo omogućiti da zaobiđete potencijalni WAF i da komunikacija putem websockets-a otkrije šemu graphQL-a:
 | 
				
			||||||
```javascript
 | 
					```javascript
 | 
				
			||||||
ws = new WebSocket("wss://target/graphql", "graphql-ws")
 | 
					ws = new WebSocket("wss://target/graphql", "graphql-ws")
 | 
				
			||||||
ws.onopen = function start(event) {
 | 
					ws.onopen = function start(event) {
 | 
				
			||||||
@ -403,7 +403,7 @@ Inspect/Sources/"Search all files"
 | 
				
			|||||||
file:* mutation
 | 
					file:* mutation
 | 
				
			||||||
file:* query
 | 
					file:* query
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
## CSRF u GraphQL-u
 | 
					## CSRF u GraphQL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Ako ne znate šta je CSRF, pročitajte sledeću stranicu:
 | 
					Ako ne znate šta je CSRF, pročitajte sledeću stranicu:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -411,7 +411,7 @@ Ako ne znate šta je CSRF, pročitajte sledeću stranicu:
 | 
				
			|||||||
../../pentesting-web/csrf-cross-site-request-forgery.md
 | 
					../../pentesting-web/csrf-cross-site-request-forgery.md
 | 
				
			||||||
{{#endref}}
 | 
					{{#endref}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Tamo ćete moći da pronađete nekoliko GraphQL krajnjih tačaka **konfiguranih bez CSRF tokena.**
 | 
					Napolju možete pronaći nekoliko GraphQL krajnjih tačaka **konfiguranih bez CSRF tokena.**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Napomena da se GraphQL zahtevi obično šalju putem POST zahteva koristeći Content-Type **`application/json`**.
 | 
					Napomena da se GraphQL zahtevi obično šalju putem POST zahteva koristeći Content-Type **`application/json`**.
 | 
				
			||||||
```javascript
 | 
					```javascript
 | 
				
			||||||
@ -425,15 +425,15 @@ Zato, pošto se CSRF zahtevi poput prethodnih šalju **bez preflight zahteva**,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
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.
 | 
					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.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Napomena je 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.**
 | 
					Napomena 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/index.html) **napada** može biti moguće exfiltrirati sadržaj sa GraphQL krajnje tačke zloupotrebom kredencijala korisnika.
 | 
					Takođe, zloupotrebom [**XS-Search**](../../pentesting-web/xs-search/index.html) **napada** može biti moguće exfiltrirati sadržaj sa GraphQL krajnje tačke zloupotrebom korisničkih kredencijala.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Za više informacija **proverite** [**originalni post ovde**](https://blog.doyensec.com/2021/05/20/graphql-csrf.html).
 | 
					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
 | 
					## Zloupotreba 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.
 | 
					Slično CRSF ranjivostima koje zloupotrebljavaju GraphQL, takođe je moguće izvršiti **zloupotrebu WebSocket-a između sajtova da 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:
 | 
					Za više informacija proverite:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -443,7 +443,7 @@ Za više informacija proverite:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
## Autorizacija u GraphQL
 | 
					## Autorizacija u GraphQL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Mnoge GraphQL funkcije definisane na krajnjoj tački mogu samo proveravati autentifikaciju zahtevaoca, ali ne i autorizaciju.
 | 
					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 [leakovanih](https://hackerone.com/reports/792927).
 | 
					Modifikovanje ulaznih varijabli upita može dovesti do osetljivih podataka o računu [leakovanih](https://hackerone.com/reports/792927).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -459,19 +459,19 @@ Mutacija može čak dovesti do preuzimanja računa pokušavajući da modifikuje
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[Spajanje upita](https://s1n1st3r.gitbook.io/theb10g/graphql-query-authentication-bypass-vuln) može zaobići slab sistem autentifikacije.
 | 
					[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 za sistem da se registruje kao novi korisnik.
 | 
					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.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<figure><img src="../../images/GraphQLAuthBypassMethod.PNG" alt=""><figcaption></figcaption></figure>
 | 
					<figure><img src="../../images/GraphQLAuthBypassMethod.PNG" alt=""><figcaption></figcaption></figure>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Zaobilaženje ograničenja brzine korišćenjem aliasa u GraphQL
 | 
					## 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.
 | 
					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 dobijanje **više instanci istog tipa** objekta unutar jednog zahteva. Aliasi se mogu koristiti za prevazilaženje ograničenja koje sprečava 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).
 | 
					Za detaljno razumevanje GraphQL aliasa, preporučuje se sledeći resurs: [Aliases](https://portswigger.net/web-security/graphql/what-is-graphql#aliases).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Dok je primarna svrha aliasa da smanji potrebu 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.
 | 
					Dok je primarna svrha aliasa da smanji potrebu 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 aliasirani upiti mogu koristiti za proveru 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 proveru više kodova za popust istovremeno.
 | 
					Razmotrite primer dat ispod, koji ilustruje kako se mogu koristiti aliasovani upiti 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 više kodova za popust istovremeno.
 | 
				
			||||||
```bash
 | 
					```bash
 | 
				
			||||||
# Example of a request utilizing aliased queries to check for valid discount codes
 | 
					# Example of a request utilizing aliased queries to check for valid discount codes
 | 
				
			||||||
query isValidDiscount($code: Int) {
 | 
					query isValidDiscount($code: Int) {
 | 
				
			||||||
@ -539,7 +539,7 @@ I zatim **koristite neke od prilagođenih**.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
### **Ranljivost duplikacije polja**
 | 
					### **Ranljivost duplikacije polja**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
**Duplikacija polja** je ranljivost gde GraphQL server dozvoljava upite sa istim poljem ponovljenim prekomerno. Ovo prisiljava server da rešava polje suvišno za svaku instancu, trošeći značajne resurse (CPU, memoriju i pozive baze podataka). Napadač može kreirati upite sa stotinama ili hiljadama ponovljenih polja, uzrokujući visoko opterećenje i potencijalno dovodeći do **Odbijanja usluge (DoS)**.
 | 
					**Duplikacija polja** je ranljivost gde GraphQL server dozvoljava upite sa istim poljem ponovljenim prekomerno. Ovo prisiljava server da rešava polje suvišno za svaku instancu, trošeći značajne resurse (CPU, memoriju i pozive ka bazi podataka). Napadač može kreirati upite sa stotinama ili hiljadama ponovljenih polja, uzrokujući visoko opterećenje i potencijalno dovodeći do **Odbijanja usluge (DoS)**.
 | 
				
			||||||
```bash
 | 
					```bash
 | 
				
			||||||
# Test provided by https://github.com/dolevf/graphql-cop
 | 
					# Test provided by https://github.com/dolevf/graphql-cop
 | 
				
			||||||
curl -X POST -H "User-Agent: graphql-cop/1.13" -H "Content-Type: application/json" \
 | 
					curl -X POST -H "User-Agent: graphql-cop/1.13" -H "Content-Type: application/json" \
 | 
				
			||||||
@ -552,9 +552,9 @@ curl -X POST -H "User-Agent: graphql-cop/1.13" -H "Content-Type: application/jso
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
- [https://github.com/dolevf/graphql-cop](https://github.com/dolevf/graphql-cop): Testira uobičajene greške u konfiguraciji graphql krajnjih tačaka
 | 
					- [https://github.com/dolevf/graphql-cop](https://github.com/dolevf/graphql-cop): Testira uobičajene greške u konfiguraciji 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/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/dolevf/graphw00f](https://github.com/dolevf/graphw00f): Prepoznaje koji se graphql koristi
 | 
				
			||||||
- [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 putanja do određenog tipa.
 | 
					- [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 putanja do određenog 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 samostalan alat ili [Burp ekstenzija](https://github.com/doyensec/inql).
 | 
					- [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://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 određenog tipa u GraphQL šemi**.
 | 
					- [https://gitlab.com/dee-see/graphql-path-enum](https://gitlab.com/dee-see/graphql-path-enum): Alat koji navodi različite načine **dostizanja određenog 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/GQLSpection](https://github.com/doyensec/GQLSpection): Naslednik samostalnog i CLI moda InQL-a
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user