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?

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 🤯

GraphQL Security

If you want to learn more on how to secure your GraphQL API, check out 9 GraphQL Security Best Practices, where we share the 80/20 steps to secure your API.

And if you need an in-depth GraphQL security check, try out Escape to run thousands of tests on your API. Or get started with a free quick scan at graphql.security.