DEV Community

Discussion on: How is GraphQL different from the old days?

Collapse
 
patarapolw profile image
Pacharapol Withayasakpunt

Now, I have to worry about SQL injection in GraphQL as well, as well as unauthorized access to CRUD.

Collapse
 
jkhaui profile image
Jordy Lee

Nah man, that's the whole point of having a middle data layer - but you WOULD have to worry about SQL injection if, like Joshua asked, you tried using SQL queries on the client
As for unauthorised CRUD access: you're going to have to deal with this no matter how you handle remote data. If you had exposed REST APIs that let anyone make put requests to your database, that's no different to unauthorised access in GraphQL or whatever other method, right?

Collapse
 
artis3n profile image
Ari Kalfus • Edited

I am a penetration tester and graphql injection is very fun. A lot of the security controls built into SQL libraries, ORMs, frameworks, what-have-you are not present in GraphQL yet. You have to do all the validation and authentication yourself, which gives you an opportunity to do it wrong.

SQL - used a prepared statement, you will never have SQL injection.
GraphQL - ???

Now if your GraphQL schema doesn't take any variables, now you only have to worry about whether I have authorization to access the subset of data I'm requesting. I've seen authentication and authorization checks on parts of a schema where some nodes are missing it. It's very easy to make those mistakes with GraphQL today - and it shouldn't be.

Edit: disable introspection on your prod GraphQL endpoint and make my job a lot harder!

Another edit: here's an article with a list of a few published findings against some brand names from graphql. I remember some of these but I didn't look at the details again. They probably have some further examples.

Thread Thread
 
jkhaui profile image
Jordy Lee

Oh fair enough, that's an area I can't comment on cos I don't know cybersecurity in-depth. So taking onboard your comment then I guess poorer security might be another current downside of GraphQL.
It's the same as any new-ish technology, it will definitely have flaws. The question is whether its advantages outweigh the disadvantages for your application. If you're building apps which are based heavily on relational data then GraphQL is probably worth considering, otherwise REST works fine for less complex apps

Thread Thread
 
artis3n profile image
Ari Kalfus

Yeah I believe that graphql is going to be awesome once it figures out these things.

Thread Thread
 
defman profile image
Sergey Kislyakov

I wonder how can one do GraphQL injections. Could you provide an example?

Thread Thread
 
artis3n profile image
Ari Kalfus • Edited

Sure - here is a page with some example techniques and it links to a lot of relevant articles.

github.com/swisskyrepo/PayloadsAll...

And

lab.wallarm.com/securing-and-attac...

Thread Thread
 
defman profile image
Sergey Kislyakov

(No)SQL injections can be prevented by prepared statements, though. Other points are valid I guess.

Thread Thread
 
artis3n profile image
Ari Kalfus

Well here's the thing - by adding a layer between the sql and the user input, you've created a way to generate arbitrary sql. Even if you use a prepared statement in the resolver, it may be possible to inject something through the graphql query.

Thread Thread
 
defman profile image
Sergey Kislyakov • Edited

Which is the case for REST API as well, isn't it? (User Input -> REST -> SQL). Or for any API in general. You can pass something like someone'; drop database prod to a REST endpoint (or any endpoint, doesn't matter which technology stack you use) and if there's no preparation done when building a SQL statement, you've done an injection. Nothing new there - always validate user input.

Thread Thread
 
artis3n profile image
Ari Kalfus

The difference is the graphql schema creates valid sql in a prepared statement, it just might not be what you would normally allow the user to retrieve.

But yes, validation of user input is key. GraphQL needs some better tooling support around that.

Thread Thread
 
defman profile image
Sergey Kislyakov • Edited

It depends on the implementation. I've once used GraphQL in a pet project and you could only pass some generic values (e.g. ids) and then select fields you want, for example:


query {
    user(id: 1) {
        login
        name
        posts {
            id
            title
        }
    }
}

id there would be passed to an ORM (Users.get(by: id).with(model: Post)) and I'd simply return this data to my GraphQL level which then would fetch everything user requested (so if my User model has id, email, etc., a GraphQL library would only take login and name from it and posts would return an array of posts that would be handled the same way) and return it to them. I've fetched everything I needed in one query compared to 2 REST calls (/api/users/1, /api/users/1/posts) and it's pretty safe as long as you prepare the id value under the hood. I doubt anyone uses GraphQL just like a SQL generator. It's not safer than exposing a raw SQL endpoint like /api/sql/$whatever_sql_you_can_come_up_with?variable=;drop everything; --lul.

Of course there are downsides such as complexity and attribute accessibility by roles, though I've implemented that by dynamic attributes that would return an error/null if you don't have permission to read this attribute. And the complexity problem was solved by the library itself - I simply put a limit on the depth of the query, so you can't do something like query { users { posts { user { posts { user ... } } } }