Hacking GraphQL Playground

GraphQL Playground has had a known XSS security issue since 2020. We give 2 very concrete scenarios to show you how it could unfold if it were to be exploited in your organization.

Hacking GraphQL Playground

A few weeks ago, we saw this known GraphQL security issue in the GraphQL playground repository:

without sanitization of user input, your application is vulnerable to an XSS Reflection Attack. This is a serious vulnerability that could allow for exfiltration of data or user credentials, or to disrupt systems. – https://github.com/graphql/graphql-playground/blob/main/docs/security/2020-xss-template-injection.md

A few days later, here's what I receive on Discord:

Image injection in Altair, a GraphQL playground

Karim - our master pentester  - quickly found a way to exploit this vulnerability to inject a script in the GraphQL client 🤯

What is an XSS attack?

XSS - or cross-site scripting - is a security vulnerability of web applications where attackers inject a script into the client web page. It can be used to bypass access control such as authentication or same-origin policy.

Example of redirecting a user with an XSS attack

Stabbed in the back...end

In cyberattack scenarios, the client is the bad guy and the server is the victim, right?

Well, what if the threat was actually coming from the server?

With this GraphQL playground vulnerability - and every GraphiQL client IDE really - some unexpected problems could be happening.

What's the risk?

Let's run through a scenario to give you a concrete example.

You want to try Github's GraphQL API before integrating it to build a CLI bot in your organization.

You head off to your GraphQL playground of choice, enter the endpoint:

https://api.gihub.com/graphql

and proceed to authenticate with your access token to see if you can indeed get access to your organization's private repos:

Authorization: Bearer {{access_token}}

You run the query to list your private repos:

query {
	viewer {
    	login
        repositories("visibility": "private") {
        	...
        }
    }
}

Nothing happens...

Oh crap! There's a typo. You missed the t in github. No big deal, right? right?

when you sent a request to the wrong endpoint

You run it again, and it works fine. You go on with your life.

Except...

This api.gihub.com injected a script in the page and took a comfortable seat in your browser while you were doing your things.

A week later, you are informed that all the company's repositories were deleted and the whole codebase leaked...

Not convinced?

Imagine if Whatsapp Business had a GraphQL API (not absurd given it's now part of Meta).

And because they care about developer experience, they decide to embed a GraphQL playground on the right side of their documentation pages to try the API while reading.

But for annoying backwards-compatibility reasons, they require you to manually type in the endpoint of the API version you currently use.

Little did they know that a shady website lives at watsapp.com (missing h)

watsapp.com redirects to this suspicious-looking website at ram22.sayasdf.com/v3/

Imagine if they were hackers - which they probably are based on the domain and look of their website - they could exploit this XSS vulnerability to:

  1. inject a script in GraphQL playground,
  2. get your cookies (as simple as document.cookie) - giving them access to your Whatsapp Business account
  3. send a phishing message to all your customers!

Sounds familiar right?

Is my own GraphQL application vulnerable to XSS Injections too?

This is now a question you should ask yourself… but figuring out the answer remains a challenge! Indeed, GraphQL is new and lacks just lacked the proper tooling, many development teams are just skipping security...

That's why 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!

x

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:

  • Injections (XSS, SQL, NoSQL…) and requests forgery
  • Resolver performance (GraphQL bombs, 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…)
  • … and more than 50+ advanced security issues!

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 minuteno credit card required.

Takeaway

Never look at APIs the same 😳

No, but seriously, this should bring your attention to the fact that not all cybersecurity attacks come from the client. Servers can also be the source of vulnerability exploits.

Now you might be thinking "Come on, this is not an actual threat. Who is going to send requests to random endpoints?". At least that was my initial reaction.

Developers don't think like hackers.

Hopefully, the examples above have shown you why this XSS vulnerability is a serious threat.

Conclusion: don't disregard a vulnerability because you don't know how to exploit it.

How to prevent XSS attacks in GraphQL Playground

The goal of this post was not to discourage you from using GraphQL Playground but to illustrate a potential security issue you might currently have in your system.

So if you decide to embed a GraphQL playground and don't have control over the consumed endpoints, you can use a sanitizer utility like xss to block potentially harmful HTML sent in the server response.

Note that `script` tags are not the only threat! The video at the beginning shows how to redirect a user with an image 🤯