Exadra37

Exadra37

GraphQL gives away to much info and this hurts it's security

Today I saw this newsletter:

The interesting bit is in the clairvoyance part of the newsletter, where it reveals us a new tool to reverse engineer a GraphQL API when introspection is disabled:

https://github.com/nikitastupin/clairvoyance

Clairvoyance allows us to get GraphQL API schema when introspection is disabled. It produces schema in JSON format suitable for other tools like GraphQL Voyager, InQL or [graphql-path-enum](https://gitlab.com/dee-see/graphql-path- enum).

Is the Absinthe library also vulnerable to this?

Most Liked

aseigo

aseigo

Well, that just isn’t true :slight_smile: The DataLoader pattern is well known and widely used with GraphQL, and that provides an easy entry point to caching beyond per-query.

That aside … security!

So, the web is, in a word, fucked. It is probably one of the least-well designed set of technologies that is so widely used, and that says a lot as there are some truly bad ideas out there in wide usage. It has such an absurdly large attack surface ranging from client-side code that is dynamically loaded from potentially random locations with little to no sandboxing (so many patchwork bandages to address that have been deployed over the years…) to server-side APIs that are neither protocols nor designed with basic concepts like secure federated authentication / authorization or progressive discovery in mind. It’s a dumpster fire which we collectively limp by on.

Just look at at venerated Internet protocols which offer no API (let alone advertise capabilities!) until authentication is performed. You don’t get “you aren’t allowed to access that” messages, you just don’t get anything at all, socket closed. And even after auth, they will expose different views on its capabilities depending on what authorization follows. This is fairly basic security stuff .. which most web technologies lack.

It isn’t all darkness, though. It’s one reason I love things like LiveView. The user authenticates, opens a socket over which authentication and authorization can be performed and then based on that capabilities can be provided. No peeking, no leakage required.

Before I moved an app recently to LiveView uploads, anyone could find out that there were various upload endpoints. Returning 404’s on incorrect uploads to pretend nothing was there would have made error recovery harder for legitimate usage (aka my own front-end apps!), and even then the latency differences between that and a “true” 404 would probably have been perceptible. Now that everything happens over a websocket and and upload capabilities are only ever advertised to users with sufficient authorization? Yeah, that hole is closed with no hackiness. (.. and yes, I do use rate limiting)

As @dimitarvp noted, GraphQL is a front-end developer convenience (and, given the mess REST APIs can be, and often are, for non-trivial access to hierarchical data, a rather useful convenience), but the world ought to just own up to the fact that HTTP based services do not provide much in the way of security or privacy.

I have serious flashbacks to telnet, ftp, and pop3 … which, btw, were all things alive and going when HTTP was initially designed.

benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

All APIs are vulnerable to this. If you do not authenticate ids, you run into trouble.

Introspection has nothing to do with their issue. The browser network tab is enough to see the API calls being made. They could do this with old school HTTP POST + JSON and it wouldn’t make any difference.

Right, and Absinthe / GraphQL won’t let you send inputs that aren’t the right type or shape either. Swagger, JSON-RPC, etc, none of them have a way at the API schema level to enforce that you are authorized to use an ID. This must be done at the application layer.

olivermt

olivermt

If giving away what your API is capable of is a security risk, you have failed some very basic security requirements imo.

It’s like saying your house is more secure if people don’t know whether or not you have a back door.

Having a lock on both your front and back door is what makes you safe.
Any GQL design that is not enforcing a kind of authorization as a parameter on every call going from a resolver to your business layer (for non-public functionality) has most likely been designed wrong.

And GQL certainly solves a bucket load more than ‘frontend convenience’
Off the top of my head:

  • Documentation that lives INSIDE your api (Swagger that doesnt suck and is harder to diverge)
  • Very easy tool to design api contracts and shape of data before you implement anything in your business layer
  • Allows you to think in data more than business actions. That is an insanely flexible feature. It is a lot easier to nail your data shape than it is to up front nail your business exposure. This increases the possibility space for innovation while still adhering to a strict data shape so you don’t get a cancerous beast of an API that falls under its own weight.
  • Composability is a lot easier in GQL as the query and mutation submission through a document is a lot easier on the developer than composing REST apis. Even the more modern APIs that supply _self and other links you can navigate by.

A client wanted my frontend dev to build out a big data dump to csv because they were losing track of their master data records. It took him half a day building a big query, collate that into a table view with a simple csv export button.

Building that in SQL (backend) or through composing REST apis (client) would have been a nightmare.

Edit: Graphql is actually so powerful in terms of query composability that I am still using it even though I’m coding liveview, because it’s easier to just re-run a query (as in client doing refetchQuery on webbrowser) than it is to do anything else. So my CUD is talking to the Service (context) modules directly, while all R is done through a Absinthe runner. Works beautiful.

I expose a split schema since we have some external dependants so one Schema is only internal and one is exposed for clients over API. They share all types and enums so it’s super easy to stay in sync.

Where Next?

Popular in Discussions Top

vans163
So useless benchmarks aside, Its possible to write a webserver that can serve 300k requests per second (perhaps more with optimizations)....
New
crispinb
On reading dhh’s latest The One Person Framework it strikes me that Phoenix with LiveView is already pretty much this. However, never hav...
New
marciol
Please, let me know if this kind of discussion already took place in another topic . Hi all, how do you consider if is better to build ...
New
saif
Hello everyone, Long time lurker first time poster here. I’ve recently begun working on Elixir full-time again! :raised_hands: It’s been...
New
shishini
I think this twitter post and youtube video didn’t get as much attention as I hoped I am still new to Elixir, so can’t really judge ...
New
PragTob
Hey everyone, this has been on my mind for some time and I’d love your input on it! TLDR: I feel like maps are superioer for storing and...
New
cblavier
Hey there, It’s been more than a year since we started using LiveView as our main UI library and building a whole library of UI componen...
New
AstonJ
If so I (and hopefully others!) might have some tips for you :slight_smile: But first, please say which area you’re finding most challen...
New
scouten
I’m looking for a host for the server part of a small (personal) side project that I’m working on. It’s currently written in Node.js and ...
New
Markusxmr
Since Drab has been developed for a while in the open, introducing the Liveview functionality in a way it happend appears to undermine th...
New

Other popular topics Top

New
senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
Darmani72
If I have a post route which an argument: post /my_post_route/:my_param1, MyController.my_post_handler How would get the post params ...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
klo
Got a question about when to concat vs. prepending items to list then reversing to achieve appending. So i know lists boil down to [1 | ...
New
komlanvi
Hi everyone, I was playing with phoenix liveView but I run into an issue. I have a form and want to validate each input text when the te...
New
Qqwy
Update: How to use the Blogs & Podcasts section You can post links to your blog posts or podcasts either in one of the Official Blog...
3271 127089 1222
New
sergio
Kind of like when jquery came out, it was super necessary. Existing drag and drop libraries have a bunch of baggage to support old browse...
New

Latest on Elixir Forum

Elixir Forum

We're in Beta

About us Mission Statement