Common GraphQL Misconceptions: A rant
Let’s talk about GraphQL, and how evil or good it is — a hot take from a developer cum pentester ;)
Common GraphQL Misconceptions
Since I am more of a pentester, I would only do a more detailed discussion on security of GraphQL, and occasionally drop-in some rants on the serious misconceptions that I myself have read in a lot of bug bounty reports relevant to GraphQL!
- GraphQL is quite insecure and has a huge attack surface!!
- GraphQL sends queries directly to the database, you can’t control what people access!
- GraphQL exposes your entire database!
- GraphQL means you have to use a graph database — exposing new attack surface
- Introspection is the real GraphQL evil — it exposes all your sensitive fields and let’s attacker read all the data.
- GraphQL’s autocorrection can also expose your schema and leak info about your APIs!
- GraphQL is this, that, blah blah blah blah blah…
And this sobbing continues when people don’t really understand what GraphQL actually is and what’s their share in security of their APIs and what GraphQL does for them…
So I guess until that distinction isn’t cleared out, this accusing would go on! So I thought why not stop it once and for all!
Not being GraphQL’s advocate but I think I have spent enough time researching on it, both as a developer and as a security researcher that I had read it’s spec, so I guess I could have an opinion on it :)
And therefore I would say, read on, and see what I have to say. Then see if that seems satisfactory or not. At the end of the day, it’s your decision but atleast make the decisions based on correct information rather than a bunch of humours you have been hearing — being passed around by people no expert in GraphQL at all!
Clearing Misconceptions
GraphQL was born in Facebook in 2012 and made it’s way into opensource stream in 2015, with React conference! And people started to think that GraphQL can only be used with React — the start of the misconceptions…
And as we moved ahead, we started to see more and more misconceptions on it and I have listed some of them above.
If you are interested to read more on the misconceptions (as a developer) and want to get the real answers for those, then I would highly recommend you to check out this twitter thread:
Btw I don’t know anything about this guy, just found this tweet related to GraphQL, so I went ahead to see what’s written there :)
Curiosity is important right ;)
But I have to say, this man knows his stuff and you should definitely check out this tweet. If you are developer, there are quite some interesting things and articles linked there. A must read I would say!
So let me use this opportunity to clear up some of the misconceptions that I talked about earlier, shall we?
GraphQL is quite insecure!!
I would say even REST APIs are quite insecure!!! Look at the OWASP API Security Top 10 list!
You get my point right?!
Everything is insecure if you don’t follow the security practices. And if you don’t then obviously it’s on you, not the fault of the poor API architecture there!
If you want a definitely list of things you want to see for making your GraphQL APIs more solid, then check out this post:
GraphQL is just a way to give you more flexibility! If you are not having AuthN and AuthZ, then it’s on you not GraphQL.
So the docs make it clear enough I suppose!
One down! Let’s see the others…
GraphQL sends queries directly to the database, you can’t control what people access!
Wait what? Who told you that? Go and read:
GraphQL uses resolver functions — so it can be thought of as a RPC-style API where you are essentially calling a bunch of resolver functions for the fields your wish to retrieve. At the end of the day, its those resolver function that get the data either from the database, the other APIs that you might be using as data sources or any other data sources for that matter.
So please let’s not confuse GraphQL with SQL :)
If you want to learn more about Resolver functions, check this out:
GraphQL exposes your entire database.
Wait no!!! Please check the last point, I hope it makes things clear.
On top of that, if your resolver function is vulnerable to SQL Injection, then why not, you entire DB is indeed exposed! But that’s your problem — seriously writing shit code in 2021 that leads to a direct SQLi — maybe reconsider your career choice?
Ah! It was the intern *cough*. Then maybe you’ll be fine ;)
GraphQL means you have to use a graph database
Again no! GraphQL just makes you think in terms of Graphs and tells you to be much more flexible and creative in thinking rather than limiting yourself and thinking in terms of tabular databases!
Seriously this is a bliss to not be constraint by the databases which we have and instead of thinking about how I would implement data fetching — via joins or something else, you instead try to go with what feels more logical! And that’s an advantage I suppose!
And since there’s no need to be tied to the data source, we can be flexible enough to use SQL, NoSQL, GraphQL databases or any other sorts of data sources — be it other APIs!
So let’s turn this point down as well :)
Don’t use GraphQL, it has a huge attack surface!
Yes and I would say even a website or an API has a huge attack surface. Even an Operating System has a huge attack surface! Your browser, and the software you install has a huge attack surface — so would you turn away all this, leave your systems and become a saint?
No right! This is just a vague point, thrown by those who either don’t know much or want to scare you from going down GraphQL’s alley!
I think you should try GraphQL yourself, see if it feels good for your use-case and then make a decision, rather than listening a 1 hour talk on how bad and insecure GraphQL can be — which ofcourse would be designed to tell you the issues that can happen with GraphQL APIs — none of which are native to GraphQL*!
* I hear some souls thinking of Introspection & Autocorrect! Fine that’s maybe one of the things that you would want to think about, when deploying your GraphQL APIs and I will cover them in the remaining 2 point!
Introspection is the real GraphQL evil — it exposes all your sensitive fields and let’s attacker read all the data.
Okay, I think this is one of those points where we meet! I get you — maybe Instrospection is bad and shouldn’t be enabled. But what if you have a public API that you wish to give away to your users? Heard of Github, anyone?
And okay fine, you get the field and schema information. What can you do if my APIs have proper AuthN & AuthZ in place and I am not giving away any extra data than you have permissions to access. Then what? Will you still complain about me giving away my API designs?
I would say, let’s face it — “Security by Obscurity” was never a sane idea!
So if you think that hiding away your API info would prevent a determined attacker, then I think you should consider your career choice. Loads of jobs around this time ;)
The point should never be about hiding what can eventually get exposed — you can’t prevent your ex-employees to shut their mouths. Could you? Maybe, maybe not. So let’s not fuss more about it!
Although, as a pentester, I would say it’s okay to keep this feature disabled in production — not due to “Security by Obscurity” — but because if you don’t want to have a functionality, then best to disable it. No wonder when this comes and bites you back.
GraphQL’s autocorrection can also expose your schema and leak info about your APIs!
Okay another one which I am quite sceptical about — why do you think that autocorrection can do much good for you, provided that I have proper AuthN & AuthZ in the first place! Still not satisfied, please read over the point above this one again, to hopefully make your mind ;)
And if you think autocorrection is not what you wish to have, disable it :)
See if you can’t do AuthN & AuthZ right, don’t blame GraphQL for it — AuthN & AuthZ is even in API Security Top 10 list, covering the first 6 spots!
So I guess even if your API documentation gets leaked, it won’t do any harm unless you miss out on Authentication, Authorization, Rate-Limiting, Mass Assignment etc.
Rant Time? Let’s do it!
When is GraphQL an issue for me?
When you think that GraphQL is a one-stop solution to the problems you have been facing with REST and jump in with half knowledge, then you shoot yourself in the foot. I don’t see anything wrong with GraphQL if you use it properly!
Autocorrection and Instrospection definitely can lead to exposure of some stuff which can them be poked for broken AuthN & AuthZ issues, but again, you as developers are in control of adding proper AuthN & AuthZ in the first place, & even disabling those autocorrection & introspection features don’t blame GraphQL, me or the *intern* for it!
Same goes for CSRF issues that have been popularized in GraphQL world and telling the world that GraphQL might be bad — but on the contrary, that can happen with REST too!
And if you do mutations over GET requests and cry about GET-based CSRFs taunting you, that’s definitely an anti-pattern, GraphQL not to be blamed there, and neither is any of your *interns*!
So I think the OWASP Top 10, if ever goes out for GraphQL, then I would bet more on misconfigs than other solid native GraphQL issues! Definitely AuthN & AuthZ are on top because that’s what devs have been missing a lot on.
But other than that, I feel it’s more about you than GraphQL being wrong :)
I hope you are not an intern reading this blog! Else I get to be the part of the drama blaming an *intern*!
Also — ranting on GraphQL advocates who think that NoSQLi are a thing of past in GraphQL, I would say consider reading more on the subject folks! Custom types are so real — JSON being popular and provided by some frameworks. So definitely watch out for use input in GraphQL too, else you would shoot yourself in the foot!
And that’s not GraphQL’s fault btw! That’s you having false assumptions and trusting your users for being friendly! Not always the case ;)
Lastly, I would say things are straight enough, let’s not complicate them by mixing in a bunch of unrelated things and then blaming GraphQL for being a villian yeah. That’s would not be good. Instead, have a open mind and see what works for you. If it didn’t helped doesn’t means it is bad but instead it’s just not the right fit for your use case. And if you see it that way, things make much more sense :)
Closing Thoughts
So with that, I would close this post. I hope this post was informational and fun to read. In case you enjoyed it, please share it among your friends in the infosec community :)
I hope these references and rant helped you clear up any GraphQL misconceptions that might be preventing you from getting that buy-in!
Let me know your feedback in the comments below and feel free to connect on twitter: @_SecurityGOAT
You can also send any topic you wish to learn more about. Send me DM on Twitter or let me know in the comments :)
Lastly, the line which should mostly be a plain ol’ boring one which I have to copy from my previous post every single time!!!! — if you have been enjoying my work and would love to support me, consider checking my Patreon page or you can even Buy Me a Coffee :)
Atleast if you read it till here, I am more than happy because this post took a lot of effort on my end :)
So it’s important that you see that effort being reflected in every word I wrote.
Shout out to all the interns who have been on the hook for the security issues that the big companies have. Not an intern but I feel your pain! Don’t let the big boyz drag you down!
See ya!
Until next time my friend, keep learning and happy hacking.