Pentesting GraphQL 101 Part 2 - Interaction
A Pentester is usually expected to be a higher than average user in terms of interaction with an endpoint. For that reason, I decided to add an intermediary step between "Discovery" and "Exploiting" called "Interaction."
This article is part of the series "Pentesting GraphQL 101".
- Pentesting GraphQL 101 Part 1 - Discovery
- Pentesting GraphQL 101 Part 2 - Interaction
- Pentesting GraphQL 101 Part 3 - Exploitation
Today's article contains three real-life examples that hopefully provide insight into the pentester mentality when dealing with GraphQL endpoint.
Prerequisites: Play Around with the endpoint
Becoming a higher-than-average user requires passing through being an average user first. For that, there is no quick or ordered guide. You have to get your hands dirty, try interacting with the endpoint, send queries, access the front-end, understand what queries do, create or change some data through mutations, and get familiar with the available types.
This knowledge is essential when developing potential attack vectors and understanding the expected behaviors.
Determining if a Query Executed
One endpoint I was pentesting had a query that fetched the metadata of a webpage given a URL, and I needed a way to determine if a query with a specific input was being executed or not.
The query was the following:
but running the same query with a random string as the url results in nothing as a response:
So a valid URL will return some data, but a random string will return nothing, and so did the malicious URL I entered, but one essential detail caught my attention ... it was the timing.
A request that triggers a request would take ten times more to execute than a request that doesn't, so this 900-millisecond discrepancy was my indicator for determining the best SSRF payload.
Finding the Underlying Code for a Closed Source Project
While doing my "Playing Around" on an endpoint, a certain query invoked an error and returned a stack trace.
At first glance, not much could be implied, but a small curiosity is necessary, so I asked about the only unfamiliar word in the stack trace, what is "saleor"?
A quick search showed that "saleor" is an open source GraphQL commerce platform. Digging deeper, I finally found "/saleor/graphql/decorators.py" on Github.
And so I partially understood the back-end architecture and had default parameters to test, such as JWT passwords set by "Saleor" if the endpoint developer missed updating them.
Vulnerability: Multipath Evaluation
Lets start with a little technical background.
Consider the following schema:
Let us also assume that the developer's goal is to restrict access to the object "character" one approach used is to restrict access through a check placed in every query or object that accesses a "character."
In our schema's case, we will have to add a check in five locations:
- "character" query
- "characters" query
- "results" field of the "characters" object
- "resident" field of the "Location" object
- "characters" field of the "Episode" object
And every time an arrow towards the "Character" object is added.
But along with the growth of the API in terms of sheer size and complexity, forgetting to place a check for a newly added query/object becomes more and more probable.
There emerges "Multipath Evaluation," where an attacker will be able to fetch information that they are not authorized to access through a path that doesn't have enough authorization checks.
To understand the extent of this vulnerability, let us see a real-life example:
We have an endpoint (introspection was disabled) of a platform where clients register, so naturally, directly accessing client information without any form of authentication should be forbidden:
And that is indeed the case. But while in the "Playing Around" step, I stumbled on the "Banks" query, which was essentially a trivial record between the server and clients, but "client" was in its fields!
Finally fetching "client" from the "banks" query actually yields results.
and just like that, we bypassed authentication while "Playing Around"
Automated security testing
At Escape, we created the first GraphQL Security scanner that allows developers to find and fix vulnerabilities in GraphQL applications during the development lifecycle before they even reach production!
It understands the business logic of GraphQL APIs and looks for more than 50 kinds of vulnerabilities so that you never have to worry again about
- Resolver performance (N+1 issues, cyclic queries, query complexity DOS…)
- Tenant isolation (access control, data segregation between users…)
- Sensitive data leaks (personally identifiable information, tokens, stack traces, secrets…)
- Injections (SQL, NoSQL, XSS…) and requests forgery
We constantly update our engine with state-of-the-art GraphQL Security research so that you never have to worry about the security of your GraphQL application again!
Start monitoring the security of your endpoints today with a 7-day free trial.
Get results in one minute – no credit card required.
Getting familiar with an endpoint is like mastering a language. The better you get in a particular language; you'll spend less time thinking of the means to convey an idea and more time on that idea itself. Similarly, for an endpoint, the better you are at interacting with that endpoint, the more time you have to think about possible attacks against it.
👉 Continue reading Pentesting GraphQL 101 Part 3 – Exploitation
Wanna know more about automated GraphQL security testing? Read our blog article "How to test your GraphQL API?".