Securing GraphQL APIs

GraphQL has revolutionized the way APIs are designed and consumed, offering flexibility and efficiency in data querying. Since Facebook introduced it in 2012, it has acquired, but so far held its niche market share within APIs. As APIs exploded, so has GraphQL with them.

However, GraphQL's flexibility also introduces several security challenges. Common security issues include injection attacks, unauthorized access, denial of service (DoS) attacks (complex query handling), excessive data exposure.

About GraphQL

When thinking of GraphQL, most developers think of exposing a relational database via an API. Whether the data is actually stored in a relational database, does not matter for the API. What matters are the relations between entity types as well as the properties of entities.

You can formulate a GraphQL query

{
    products {
        name
        vendor {
            name
        }
    }
}

to retrieve a list of products (with their names as well as their vendor's names).

The data might be stored in two relational tables (called products and vendors, linked by a foreign key), or in a totally different way: GraphQL just describes the query syntax.

GraphQL is often preferred in architectures where

Potential pitfalls

While the mental model described in the previous paragraph is correct (and standardized in the last GraphQL specification to date, the "October 2021 Edition"), it does not cover the the whole picture:

Membrane API Gateway's GraphQL Protection feature attempts to help you as good as possible.

Usage

<spring:beans xmlns="http://membrane-soa.org/proxies/1/"
                xmlns:spring="http://www.springframework.org/schema/beans"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                http://membrane-soa.org/proxies/1/ http://membrane-soa.org/schemas/proxies-1.xsd">
  <router>

    <request>
        <graphQLProtection maxRecursion="2" />
    </request>
    <target url="https://www.predic8.de/fruit-shop-graphql" />

  </router>

</spring:beans>
More fine-grained configuration options are also available.

Other Protections

Attacks using Injection or Cross Site Scripting usually rely on using special characters like single quotes (') or left angle brackets (<).

We advise combining Membrane API gateway with a Web Application Firewall (WAF) like Snort to protect against these types of attack. Membrane will take care of validating the general GraphQL syntax and/or blocking specific GraphQL-related features in this scenario.

Rate Limiting might also help reduce the exploitability of existing weaknesses so far, that they become irrelevant (e.g. guessing the correct password/access key).