Join our newsletter

All The Knobs - GraphQL Security Guardrails

All The Knobs - GraphQL Security Guardrails

Shahar Binyamin·

So far, we've covered GraphQL Security Awareness and have understood that No, You Don't Need to Disable Introspection. Now, let's take a look at the different security knobs needed to guardrail a healthy GraphQL request.

It’s All About DoS

GraphQL DoS (Denial of Service) attacks target GraphQL parsers, GraphQL resolvers, and the underlying DBs in a single API call. They include batching, nested, heavy and complex, N+1, and circular attacks which can bring your server down and affect server availability.

Fortunately, it is possible to protect your server from these attacks with the help of a set of guardrails and GraphQL usage-based rate-limiting.

All the knobs - GraphQL Attack Surfaces.png

How to Protect - Inbound

Below is a list of security knobs that any GraphQL adopter should implement. Ideally, these configurations are set together with per-role access control to limit attacks.

All The knobs - GraphQL Security - Inbound.png

Limit Directives

As one of our favorite security knobs, limit directives help to guard against parser overload attacks. Overloading the parser with hundreds of directives can result in the server crashing without the request reaching the resolvers. (Credits: @unixhopper)

GraphQL Limit Directives for Parser Attack.png

Limit Depth

Helps to guard against nested and N+1 attacks that overload resolvers and DB with complexity and loops.

GraphQL Limit Depth for Nested Attack.png

Limit Height

Helps to guard against alias attacks like overloading DB access for the same field or type.

GraphQL Limit Height for Alias Attack.png

Limit Root Fields

Helps to guard against batch attacks like password guessing and OTA bypassing.

GraphQL Limit Root Fields for Batch Attack.png

Limit Request Size

Offers fallback protection for complex requests by limiting the size of the request.

Force Operation Name [Bonus]

Make sense of your analytics and telemetry. While the uniqueness of the name can’t be enforced, having a name makes it much easier to gain context of the call and differentiate it from other calls when reviewing API usage.

GraphQL Improve visibility and force name.png

How to Protect - Outbound

Demand-based Rate Limiting (aka Usage-based)

We found that the most robust way to think about GraphQL Rate Limiting is to look at the server’s consumption and real usage. Counting each query’s returned objects against a timeframe limit (e.g. 1,000 credits per minute).

Credits can be configured in a few ways:

  • Statically Configured - All objects are counted as 1 credit.
  • Manually Configured - Since not all fields are equal, some may take more time to retrieve than others (e.g. computed fields). In this configuration, developers can manually assign different credit weights to different types and fields.
  • Dynamically Configured - Credits are calculated based on the GraphQL tracing and server time to respond.

This approach works best with granular access control, where heavy-usage roles have a larger allowance as opposed to other roles or even unauthenticated calls.

Cost Analysis-based Rate Limiting (aka Predictive-based)

Alternatively, if you are using GraphQL-JS, there are a few libraries that might help to predict the complexity of a query:

Limit Response Size

If all else fails, limit the size of the response.

What’s Next

Ready to defend against GraphQL server attacks? Inigo can help! Connect with us today.

Inigo offers a platform-agnostic approach to remove barriers and open possibilities for any open-source or commercial GraphQL server.

Be sure to subscribe to our newsletter to get notified of our next posts, where we dive deeper into GraphQL-specific attacks.