As GraphQL gains popularity, security researchers and bug bounty hunters need to stay on top of vulnerabilities in GraphQL-based systems.
Everyday more and more companies are deciding to replace their REST APIs in favor of GraphQL for their web and mobile applications. There are numerous benefits with using GraphQL, such as solving the over-fetching and under-fetching problems many REST APIs face, thus allowing for more performant and efficient applications. However, as companies like Shopify, Wealthsimple, PayPal, Github, and Atlassian shift their investments to this new API technology are you?
Many security researchers and bug bounty hunters who are asked to evaluate GraphQL APIs often scrabble last minute to ramp themselves up on what GraphQL is, how it works and what common vulnerabilities it may have. Now before we give you a high-level guide on what you should be looking out for in this blog post, it's important to note that simply running a set of hacking utilities or tools IS NOT a comprehensive way of running a security assessment.
All GraphQL security assessments should be conducted by experienced professionals who have deep subject matter expertise in GraphQL - which is why ASEC is encouraging everyone to dive deep into the world of GraphQL hacking by checking out our new book Black Hat GraphQL - written by Nick Aleks & Dolev Farhi, published by No Starch Press.
We also wanted to let hackers know that we will be offering online training specialized in Offensive GraphQL Security. We've broken down the online training into two parts.
Part one is a Foundation GraphQL API Attack Surface Training Course, perfect for folks who aren't familar with GraphQL. This crash course into GraphQL will give you a hands-on approach to learning about how this rapidly adopted API technology works and how its internals can be used as attack vectors.
Part two is the Advanced Offensive GraphQL Security Training Course. This hacking course builds on top of the foundational knowledge you gained about GraphQL's internals in part 1. Leveraging a custom hacking lab, you’ll delve into the details of how to execute numerous GraphQL attacks.
Our ASEC blog will provide a high level overview for how to execute reconnaissance, information disclosure, denial of service, authentication & authorization bypasses, injection and request forgery & hijacking against GraphQL. This blog post however, will only focus on reconnaissance, stay tuned for more blog posts and guides.
Step 1: Port scan the target web application
It’s important to run a comprehensive port scan because multiple GraphQL services may run on different ports of your target system. Using a tool like nmap would be perfect to identify all running instances of GraphQL.
Step 2: Detect all GraphQL endpoints including GraphiQL and GraphQL playgound
GraphQL services like GraphiQL or GraphQL Playground may run behind multiple endpoints, it's important to hunt for and list all the active GraphQL service endpoints. You can use a specialized GraphQL detection tool we built called graphw00f to detect all running GraphQL services and endpoints.
Running graphw00f in detection mode to detect endpoints
python3 main.py -d -t https://example.com
Note: Some staging/development instances of GraphQL may also be running on subdomains against your target, you can use graphw00f to detect those staging endpoints as well.
Step 3: Fingerprint the GraphQL implementation
The first real step to identifying potential weaknesses in a graphql target is to fingerprint the underlying technology and language running the service. You can go ahead and use graphw00f to also fingerprint the implementation by running it with the -f argument.
python3 main.py -f -t https://example.com/graphql
Step 4: Identify any GraphQL implementation vulnerabilities & weaknesses
Using another hacking utility we developed at ASEC, the GraphQL Threat Matrix is the industry go-to resource for gathering information on default configurations, features and vulnerabilities within the most popular GraphQL implementations.
Step 5: Review implementation validations
All GraphQL query requests are tested for their validity against the schema and type system before they are executed and resolved by the server. These implementation validations vary from implementation to implementation and can be reviewed in the GraphQL Threat Matrix.
Noting what validations are executed by a given GraphQL implementation helps to identify potential vulnerabilities like the one in CVE-2022-30288, where versions of Agoo (a GraphQL implementation) before 2.14.3 do not follow the GraphQL spec and validate requests for fragment cycles.
Step 6: Check for an authentication layer
By sending a few simple canary queries (like the one below) to your target GraphQL server you should be able to detect whether or not an authentication layer is implemented.
query {
__typename
}
Seeing any of the following error responses are key indicators that the following authentication controls are in place.
Error |
Possible Auth mechanism |
Authentication credentials are missing.
Authorization header is required...
|
OAuth2.0 Bearer with JWT |
Not Authorised!
|
GraphQL Shield |
Not logged in
Auth required
API key is required
|
GraphQL Modules |
Invalid token!
Invalid role!
|
graphql-directive-auth |
Authentication and authorization controls that are built into a GraphQL API is a poor security practice and when you come across this scenario there are a number of attacks that you can test for (but we'll discuss this in another blog post).
Step 7: Check for introspection status
Introspection allows you to peer into the GraphQL schema used by the target application. Running the following query can help you gather valuable intelligence about the custom object types, directives, data model and relationships used within the application. Running the query below should return a like of all types and their names from the GraphQL schema.
query {
__schema {
types {
name
}
}
}
If introspection is not enabled, you can attempt to abuse the field suggestions feature built into many GraphQL implementations to effectively brute force the schema. A great tool that you can use to bypass disabled introspection is clairvoyance.
Step 8: Check for query depth or cost limits
Query depth limits are a common GraphQL control used to prevent denial of service attacks using recursively nested queries. If you have access the the schema file you can visualize it with a tool like Voyager to highlight these two-way linked relationships. You can test for query depth limits by sending a deeply nested query such as:
query {
user {
friends {
user {
friends {
...
}
}
}
}
}
Query cost analyzers are another defense control used by many GraphQL implementations and it can be deployed in many ways, they can use static field-level costs, a credit-based system, or even dynamically calculate cost based on the server response. Regardless of the type of cost analysis used, you can craft a massive query to find out.
Step 9: Identify GraphQL timeouts (if any)
Some GraphQL implementations like graphql-ruby allow setting a timeout on the query execution as a way to protect against long-running and resource-consuming tasks. By sending large queries with duplicate fields or deeply nested relationships you should be able to identify if the server implements timeout checks.
Step 10: Check for alias or array query batch limits
A single HTTP request has the power of executing multiple GraphQL executions. This is important especially when probing an API for the ability to cause denial of service attacks or authentication brute force attacks. https://github.com/dolevf/graphql-cop There are generally two GraphQL batch features you can check for that allow you to execute multiple actions with a single request:
Array-based query batching example
curl http://example.com/graphql -H "Content-Type: application/json" \
-d '[{"query":"query {user}"},{"query":"query {user}"}]'
Alias-based query batching example
query {
alias1:user
alias2:user
alias3:user
alias4:user
}
Batching multiple GraphQL operations into single HTTP requests is extremely useful for enumeration and brute-forcing attacks. Two tools you can use to assist with your batched attacks are BatchQL (Array-based batching) and CrackQL (for Alias-based batching).
Step 11: Check for debug modes
A few GraphQL implementations support debug mode, which provides additional information in the response of a query. Check to see if this mode is turned on or if you can remotely enable to introduce information disclosure issues.
Step 12: Identify any Web Application Firewalls (WAFs)
Finally, identifying any web application firewalls is a key reconnaissance task. Especially when attempting to actively probe and attack any APIs. Knowing the WAF protecting a GraphQL API can help identify potentially bypass techniques for future tests.
If any of the above concepts and instructions shared with you seem foreign, don’t worry, we've got your back. All of these concepts and hands-on instructions for how to execute them are provided in a free chapter of our book, Black Hat GraphQL.
Proactively monitor all of your applications, servers, endpoints and cloud infrastructure by combining automation and expert-driven testing to continuously identify and remediate vulnerabilities.
Request a Demo Learn more