GraphQL for Bug Bounty

Mudhalai Mr
Developer Community SASTRA
5 min readApr 2, 2021

GraphQL is getting popular day by day. Currently, it is being used by tech giants like Facebook, Twitter, Github, and many more. In this blog, we will explore what GraphQL is and how to test GraphQL endpoints for vulnerabilities.

Image Credits: Google

What is GraphQL:

GraphQL is a query language for APIs designed to provide a more efficient, powerful, and flexible REST alternative. It is based on declarative data sampling, that is, the client can specify exactly what data he needs from the API. Instead of multiple API endpoints (REST), GraphQL represents a single endpoint that provides the client with the requested data.

GraphQL vs REST:

Image Credits: Google

In REST API we have to use separate endpoints to get different information but in GraphQL, the GraphQL server handles all the requests and returns only the requested information.

If you are a company like Facebook you would probably have lots of data on a single user and some of it is considered sensitive if you want only the username and the first name there are two ways to get them from a REST API:

  1. You can request all the data of that person and display only the required ones but it is not a good idea to do that filtering on the client-side.
  2. You can request the username first and then the first name but what if we need like 10 or 15 fields? no of requests made will also increase.

GET /rest-api-v2/user_id/usernames

GET /rest-api-v2/user_id/ firstnames

But in GraphQL you can request only the data you want and the server will only return the requested data, you can also control which data can be requested and cannot be requested in GraphQL.

{
user(id: user_id){
username
firstname
}
}

GraphQL Schema:

A GraphQL schema is at the core of any GraphQL server implementation. It describes the functionality available to the client applications that connect to it. (It is like a blueprint) You can learn more about it here:

Types of Requests:

1.Query:

To read data,

query {
allUsers{
userName
}
}

2.Mutation:

To create, modify and remove data,

mutation {
createUser (userName:"user1") {
userName
}
}

Here we also get data from the server to verify the user profile is created.

To learn more: https://graphql.org/learn/queries/

Now that you have learned some basics on GraphQL, let’s hack!!

GIF credits: giphy

Introspection Query:

Github API

Introspection query allows us to get information about what queries GraphQL schema supports, this will give us a clear idea about the fields present and we can use it to send our own requests. The introspection query is turned on by default so it is worth trying.
https://docs.github.com/en/graphql/overview/explorer

Hackerone

Common Directories and Endpoints:

Finding development endpoints may lead to an unstable endpoint which may be easy to exploit than the production endpoints.
Developers use consoles or IDEs to work with GraphQL if we could find these endpoints we will discover a larger attack surface to test. Also, these consoles may contain features and privileges to send introspection queries, some of the common directories are:

/v1/*
/v2/*
/beta/*

/graphql
/graphql/console
/graphiql
/graphql.php
/graphiql.php
/explorer
/altair
/playground

IDOR:

GraphQL queries can be manipulated by changing the requested values and by exploiting the IDOR vulnerability we could get private data.

We can also brute force the query fields which may give us some hidden data.

{
singleUser (user:
1)
{
apiKey
name
surname
dateOfBirth
}
}

https://hackerone.com/reports/717716

Authentication and Authorization:

There are no built-in authentication and authorization features, the developers have to implement them themselves or use third-party libraries. This increases the chance of finding logic and implementation errors.

SQL Injection:

As GraphQL is the only way to communicate with the backend and database servers it is possible to exploit SQL injection. GraphQL doesn’t do any filtering by itself, developers have to implement them,

mutation search($filters Filters!){
authors(filter: $filters)
viewer{
id
email
firstName
lastName
}
}

{
"filters":{
"username":"paolo' or 1=1--"
"minstories":0
}
}

NoSQL Injection: http://www.petecorey.com/blog/2017/06/12/graphql-nosql-injection-through-json-types/

Denial Of Service:

Remember the XML Billion Laughs attack? GraphQL has something similar to it,

type Thread {
messages(first: Int, after: String): [Message]
}

type Message {
thread: Thread
}

type Query {
thread(id: ID!): Thread
}

Look at this code block, we can query messages of a thread and thread of a message. This means we can repeatedly do that, which puts a heavy load on the server at some point it will crash the server.

query maliciousQuery {
thread(id: "some-id") {
messages(first: 99999) {
thread {
messages(first: 99999) {
thread {
messages(first: 99999) {
thread {
# ...repeat times 10000...
}
}
}
}
}
}
}
}

GraphQL is not as popular as REST but it is growing and efficient than REST API as the digital data economy thrives GraphQL is not going anywhere. So, it is worth getting good at GraphQL, and here are some resources to continue your quest.

https://medium.com/the-graphqlhub/graphql-and-authentication-b73aed34bbeb
https://www.hackerone.com/blog/the-30-thousand-dollar-gem-part-1
https://www.youtube.com/watch?v=NPDp7GHmMa0
https://github.com/doyensec/inql
https://youtu.be/OQCgmftU-Og

Спасибо :)Mudhalai Mr DSC SASTRA deemed university

--

--

Mudhalai Mr
Developer Community SASTRA

<>AKA Gowtham Student at SASTRA Deemed university, Core team member DSC SASTRA </>