New Series: Hacking GraphQL Zero to One
Learning a new thing is always rewarding in security. It will broaden your understanding on something, broaden your attack surface, and do not keep you hanging when you are face to face with a real-world scenario. We will focus on GraphQL since many websites like for example Upwork uses it. In near future we can see more adoption to GraphQL. So, let's dive into it.
Most of the ideas are taken from Portswigger Websec Academy. I am also learning along the way.
Comparing it with REST APIs ,GraphQL do not have different endpoints for different APIs. It uses the same endpoint. Its a query language for your API. For example here is a query.
{
me {
name
}
}
This will return
{
"data": {
"me": {
"name": "Luke Skywalker"
}
}
}
You can try these queries out in the official docs : https://graphql.org/learn/
These are the places you can see these APIs, add them into your directory wordlists (should be present already).
/graphql
/api
/api/graphql
/graphql/api
/graphql/graphql
The above example raises some questions on security, how do we make sure another person cannot access one's data through queries ? If this is missed by the developer can lead to an IDOR.
GraphQL has Introspection feature to ask a GraphQL schema for information about what features it supports. This developer features can prove to be enumeration helper.
Query :
query {
__schema {
types {
name
}
}
}
Results:
{
"data": {
"__schema": {
"types": [
{
"name": "Query"
},
{
"name": "String"
},
{
"name": "ID"
},
{
"name": "Mutation"
},
{
"name": "Episode"
},
{
"name": "FilmRating"
},
{
"name": "Film"
},
{
"name": "Character"
},
{
"name": "Int"
},
{
"name": "LengthUnit"
},
{
"name": "Human"
},
{
"name": "Float"
},
{
"name": "Droid"
},
{
"name": "FriendsConnection"
},
{
"name": "FriendsEdge"
},
{
"name": "PageInfo"
},
{
"name": "Boolean"
},
{
"name": "Review"
},
{
"name": "ReviewInput"
},
{
"name": "Starship"
},
{
"name": "SearchResult"
},
{
"name": "__Schema"
},
{
"name": "__Type"
},
{
"name": "__TypeKind"
},
{
"name": "__Field"
},
{
"name": "__InputValue"
},
{
"name": "__EnumValue"
},
{
"name": "__Directive"
},
{
"name": "__DirectiveLocation"
}
]
}
}
}
So, this feature should be disabled in production. So that this is unavailable to hackers.
There is a tool which you can use if introspection is disabled: clairvoyance
Let's jump into a quick lab:
We are provided with a blog website, with few blogs.
The blogs use GraphQL APIs in the backend. Let's setup burp and run the intersection. Setup burp in chrome.
Out task : Find secret hidden in one of the hidden blog posts.
We can run the Introspection query on burp with a right click -> GraphQL -> add introspection query
This helps us find a secret parameter.
Change the id to 3 (missing id) and add postPassword into the query.
Hope this series would be useful to you. Stay tuned for more.
LiveReview helps you get great feedback on your PR/MR in a few minutes.
With LiveReview, you get fast, AI-powered code reviews that improve quality without slowing you down.
If you're tired of waiting for your peer to review your code or not confident that they'll provide valid feedback, here's LiveReview for you.