Hacking GraphQL API Using Suggestions
Hello Hackers! I am Inderjeet Singh aka encodedguy from India. In this blog, I will introduce a way to hack GraphQL API using suggestions. At the end, I will also review one of my own finding where I was able to make a custom GraphQL query using suggestions and dump internal data.
What is GraphQL?
An API technology that is better than REST API in some terms but has its cons as well. Unlike REST APIs, it gives clients data that is requested. If client requests for user/<userid>/photos in REST API, he may get photos + user data as well. But, with GraphQL a query will only respond with the photo URLs or path only.
GraphQL Request Format:
Let's talk about suggestions
GraphQL API has a nice feature of giving suggestions. If the client does not requests correct name of the query, mutation, argument, fields, etc. then server in the response will give suggestion that the correct name could be this or that.
Example: Suppose that user enters the query name as "creativity", and if the query name is something like "createdAt", "createdBy", etc. then those suggestions are contained in the response.
How do I test this?
Well, this idea hit me when I was working on a internal graphql application that has GraphQL Introspection disabled. And, I tried to request a random query but it gave me a suggestion. That's how it all started.
So, I made a query like this:
If the query name is correct it would give me the details, if it is incorrect it would may give me some suggestions.
So I FUZZZED. I started fuzzing the query name, argument name, field names, and everything that suggestions pointed me after this. After 8 hours of fuzzing, I was able to enumerate a query with so many fields, that gave me internal data of developers.
The final query has more fields, I am hiding some details here to respect the program's policy.
How to Leverage Suggestions as a Hacker?
These are some cases when a hacker can use GraphQL suggestions:
- Introspection schema or the documentation don't have all possible queries and mutations. Some of them can be in development phase. An attacker can enumerate these queries using suggestions.
- Check if the introspection is disabled. Like in my case the introspection was disabled, so the suggestions made my work too easy but took so much time.
- Also, check if there is some Authorization required or not. A valid access token could be required to request queries. Try to create account if possible, if not move on to next function (that's how bugbounty works!!)
- Tip: Use Burpsuite Intruder to FUZZ the query, mutation, fields, etc. as the response is also visible there and use a wordlist of common graphql-words.
Based on the length of the response, we can filter if the response contains some suggestions or not.
One more tip: Instead of fuzzing with a Sniper attack so many times, do a pitchfork attack at many fields, arguments, queries at the same time. This statement could be hard to grep for beginners but belive me if you understand the basics of GraphQL properly, with a pitchfork attack you can save so much of time. I got this idea, when I was hacking one of the Yahoo's GraphQL server.
- Find queries that are not in production yet.
- Could result in massive data leak.
As a bug bounty hunter, I am not actually aware about the correct prevention steps. But the below github issue give some ways for mitgating this.
Read this issue: https://github.com/apollographql/apollo-server/issues/3919
I think this is enough for a blog, I would make a video soon on this on my Youtube channel: "rashahacks" to introduce this vulnerability again in more depth.
Ping me on Twitter @3nc0d3dGuY.
Thank you for reading!!
Hack the GraphQL!!