What is GraphQL?
GraphQL is a query language that was created by Facebook and made public in 2015. It offers an alternative to using REST APIs for data retrieval.
GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data. It provides a common language that your backend can use to provide data to your frontend. In a security context, GraphQL can be useful because it allows clients to specify exactly what data they need from an API, which can help reduce the risk of over-fetching or under-fetching data.
Additionally, GraphQL has built-in mechanisms for specifying the type and shape of data that can be queried, which can help prevent clients from accessing sensitive data or triggering unintended side effects. Overall, GraphQL can help improve the security of your data and your APIs by providing a standardized way for clients to access and manipulate data.Although you may not be aware of it, you may already be using GraphQL, as it is used by several major technology companies such as Facebook, GitHub, Pinterest, Twitter, and HackerOne. These companies rely on GraphQL to power their APIs and provide data to their clients.
Why GraphQL?
GraphQL was created to address the need for greater flexibility and efficiency in API development. It solves many of the challenges and limitations that developers encounter when working with REST APIs, such as lack of flexibility and the need for multiple round trips to the server to fetch data.
- Avoid Over- and Underfetching: we only fetch what we need from the server by constructing our query to only include what we need.
- Prevent multiple API calls: In case you need more data, you can also avoid making multiple calls to your API. In the case above, you don't need to make 2 API calls to fetch
/order
and/product
separately. - API Versioning: When the need for new features arises, you can easily add additional fields, queries, mutations, etc. to the server without affecting other parts of the application. Additionally, it is easier to remove old features and make them backward compatible without causing breaking changes. This allows for greater flexibility and maintainability in the long term.
- Self-documenting: Every GraphQL API conforms to a "schema" which is the graph data model and what kinds of queries a client can make.
GraphQL analogs of typical REST-ish terms
Requirement | REST | GraphQL |
---|---|---|
Fetching data objects | GET | query |
Inserting data | POST | mutation |
Updating/deleting data | PUT/PATCH/DELETE | mutation |
Watching/subscribing to data | subscription |
We can discuss more on these later!
How to identify the GraphQL Endpoint
Common GraphQL Endpoints
- /graphql
- /graphql/console
- /graphql.php
- /graphiql.php
- /explorer
- /altair
- /playground
1. Fuzzing
Start fuzzing your target by including the below endpoints in your word list using your favourite bruteforce tools. I'm a fool, so I use FFuF
Wordlist:
Command:
ffuf -w graphql.txt -u https://target/FUZZ
2. Nuclei
Use Projectdiscovery's Nuclei to detect the GraphQL endpoint.
Template: graphql-detect.yaml
Command:
#List of targets
nuclei -t graphql-detect.yaml -l target_domains.txt
#Single target
nuclei -t graphql-detect.yaml -u https://example.com
3. graphw00f
GraphQL server fingerprinting using graphw00f
Command:
python3 main.py -f -d -t http://localhost:5000
Keep an eye on Burp Suite logs and use the search functionality to see if your target use graphql
Once you identified the GraphQL endpoint then proceed with the below checks.
Introspection Query Enabled
One common mistake in configuring GraphQL is having the Introspection query enabled
In GraphQL, an introspection query is a special type of query that can be used to retrieve the schema for a GraphQL API. This schema defines the types of data that the API can return, as well as the fields that are available for those types and the arguments that can be passed to those fields.
Introspection queries are useful for a variety of purposes, such as generating documentation for an API or helping to debug an issue with the schema. To execute an introspection query, the client can send a query with the __schema
field to the server, which will return the complete schema for the API.
Here is an example of a simple introspection query in GraphQL:
query { __schema { types { name fields { name type { name kind } } } } }
This query will return the names and field definitions for all of the types in the schema. The kind
field in the response can be used to determine the type of the field (e.g. whether it is an object, scalar, or enum type).
{ "data": { "__schema": { "types": [ { "name": "Query", "fields": [ { "name": "users", "type": { "name": null, "kind": "NON_NULL" } }, { "name": "user", "type": { "name": "User", "kind": "OBJECT" } } ] }, { "name": "User", "fields": [ { "name": "id", "type": { "name": "ID", "kind": "SCALAR" } }, { "name": "name", "type": { "name": "String", "kind": "SCALAR" } }, { "name": "email", "type": { "name": "String", "kind": "SCALAR" } } ] } ] } } }
To determine whether introspection is enabled on a GraphQL endpoint, you can make a POST
request to the endpoint with the following query:
Introspection query:
{__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}}}}}}}}
If introspection is enabled, this query will return all the information about the schema for the API. If introspection is not enabled, the server will return an error.
The introspection query response might be huge unreadable JSON and it's easy to get overwhelmed, been there!
Schema visualization
The best way to understand the schema is to visualize it.
1.GraphQL Voyager
Navigate to GraphQL Voyager to visualise the schema, this is my go-to website to understand the Graphql schema.
Click on change schema and then select the Introspection tab, as shown in the figure below.
Paste the introspection query response into the text box and click on display, as shown in figure below.
Schema now became much more understandable
2. Graphql Visualizer
Graphql Visualizer run the introspection query against a GraphQL endpoint. Paste the result into the textarea below to view the model relationships.
The introspection visualization section will show us the schema
3. GraphQL Editor
GraphQLEditor makes it easier to understand GraphQL schemas. Free service will be sufficient for us.
- Navigate to https://app.graphqleditor.com/ and login.
- Create a new project.
- Click on import scheme on the right side, import from file or URL and click on submit
4. Click on relation on the left menu
Now the chunky confusing JSON looks much better! Now we have a better understanding of the schema.
What if Introspection query is disabled ?
It was all good till we found that introspection is disabled on your target, what will you do next. Don't worry, GraphQL have a feature for fields and operations suggestions. If you made an typo in query, graphql tends to ask did you mean xyz?.
There are tools that abuse this suggestions to determine Obtain GraphQL API Schema
clairvoyance
Obtain GraphQL API Schema even if the introspection is not enabled using clairvoyance
Command:
#installation
pip install clairvoyance
#usage
python3 -m clairvoyance -o schema.json https://example.com/graphql
Put your brain to use
I challenge you!
- Navigate to the site "https://lucasconstantino.github.io/graphiql-online/"
- Check if the Introspection Query is enabled or not?
- If yes, then visualize the GraphQL Schema with your favorite method.
- Take a screenshot and share it with me on Twitter cyph3r_asr.
- Share this amazing blog 😉😜.
If you found the 1 month pentester lab pro subscription, congratulation 🎉 and you can thank Infosecwriteups!
Check out there new forum: houseofhackers