Gebna

Secure Your GraphQL API With This One Line of Code

Written by Bahaa Zidan

One the greatest things about having a GraphQL API is the flexibility it gives your users to query the types you expose. A user can choose to query one field in one type or they can choose to query every type you expose. That’s great and all but it opens the door for a very dangerous denial-of-service attack.

Imagine your GraphQL schema have two types: Author and Article.

type Author {
  name: String
  articles: [Article]
}
 
type Article {
  title: String
  content: String
  author: Author
}
 
type Query {
  articles: [Article]
}

This is a valid GraphQL schema. Let’s try to query it:

query GetArticles {
  articles {
    title
    content
    author {
      name
      articles {
        title
        author {
          name
        }
      }
    }
  }
}

This will return a list of articles and with each article return its’ author. And since type Author can also return the list of articles and each article can return an author, this query can theoretically have infinite depth. An attacker can write a simple script that generates a query that’s a million deep. Your server will most definitely crash or suffer from extremely degraded performance trying to resolve such a query.

There’s a very easy fix to this specific attack. We limit the depth any query can have. If a query have more we simply return BAD_INPUT error. This can be achieved by using a validation rule in your GraphQL server. I’m using apollo-server here. But most GraphQL servers support this feature. We don’t even have to define this validation rule ourselves. There’s a ready made package for it:

npm install graphql-depth-limit

After that we just need to write one line of code to our graphql server configuration:

validationRules: [depthLimit(10)];

That will result in the following apollo-server config:

const server = new ApolloServer({
  typeDefs,
  resolvers,
  validationRules: [depthLimit(10)],
});

Here I’m limiting the depth to 10. You can tweak that to your liking.

This by no means is the full story when it comes to securing a GraphQL API or a backend in general. But it’s a very easy tweak that enhances the security of your API.