---
searchable: false
---

import { Callout } from '@theguild/components'

# Secure your Gateway

Building a secure GraphQL API is hard by design because of the “Graph” nature of GraphQL. Libraries
for making different aspects of a GraphQL server secure have existed since the early days of
GraphQL. However, combining those tools is often cumbersome and results in messy code. With envelop
securing your server is now as easy as pie! Hive Gateway has a built-in security layer that helps
you to secure your Gateway. But in most of time, this security layer is not enough or needed to be
customized for your use case.

## Protection against Malicious GraphQL Operations

One of the main benefits of GraphQL is that data can be requested individually. However, this also
introduces the possibility for attackers to send operations with deeply nested selection sets that
could block other requests being processed. Fortunately, infinite loops are not possible by design
as a fragment cannot self-reference itself. Unfortunately, that still does not prevent possible
attackers from sending selection sets that are hundreds of levels deep.

The following schema:

```graphql
type Query {
  author(id: ID!): Author!
}
type Author {
  id: ID!
  posts: [Post!]!
}
type Post {
  id: ID!
  author: Author!
}
```

Would allow sending and executing queries such as:

```graphql
query {
  author(id: 42) {
    posts {
      author {
        posts {
          author {
            posts {
              author {
                posts {
                  author {
                    posts {
                      author {
                        posts {
                          author {
                            id
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
```

There are a few measurements you can use for preventing the execution of such operations.

A handy tool for analyzing your existing GraphQL operations and finding the best defaults for your
use case is [`graphql-inspector`](https://www.the-guild.dev/graphql/inspector).

Learn more about `graphql-inspector audit`
[here](https://the-guild.dev/graphql/inspector/docs/essentials/audit).

### Persisted Operations

Instead of allowing any arbitrary GraphQL operation in production usage, we could use an allow-list
of operations that the server is allowed to execute. We can collect such a list by scanning the
code-base and extracting the list of operations.

[Learn more how to configure persisted operations](/docs/gateway/persisted-documents)

### Reject Malicious Operation Documents

Parsing a GraphQL operation document is a very expensive and compute intensitive operation that
blocks the JavaScript event loop. If an attacker sends a very complex operation document with slight
variations over and over again he can easily degrade the performance of the GraphQL server. Because
of the variations simply having an LRU cache for parsed operation documents is not enough.

A potential solution is to limit the maximal allowed count of tokens within a GraphQL document.

In computer science, lexical analysis, lexing or tokenization is the process of converting a
sequence of characters into a sequence of lexical tokens.

E.g. given the following GraphQL operation.

```graphql
query {
  me {
    id
    user
  }
}
```

The tokens are `query`, `{`, `me`, `{`, `id`, `user`, `}` and `}`. Having a total count of 8 tokens.

The optimal maximum token count for your application depends on the complexity of the GrapHQL
operations and documents. Usually 800-2000 tokens seems like a sane default.

You can limit the amount of allowed tokens per operation and automatically abort any further
processing of a GraphQL operation document that exceeds the limit with the
[Max Tokens Plugin](/docs/gateway/other-features/security/max-tokens).

Also this can be combined with
[Character Limit](/docs/gateway/other-features/security/character-limit) that limits the number of
characters in the query and mutation documents.

### Gateway -> Subgraph HMAC Signing

When you have multiple subgraphs and a gateway, you might want to ensure that the requests to the
subgraphs are trusted and signed by the gateway. This is handy in case your want to ensure that the
requests to the subgraphs are trusted and signed by the gateway, and no other entity can execute
requests to the subgraph.

In case of any missing signature, tampering or unauthorized access, the subgraph services will
reject the request.

We recommend using HMAC signing for requests between the Hive Gateway and the upstream in cases
where authentication plugins are involved, in order to ensure the gateway is the only entity that
can execute requests to the subgraph on behalf of the end-users.

You can use the [HMAC Signature plugin](/docs/gateway/other-features/security/hmac-signature) to
perform requesting signing and verification.

### Query Depth Limiting

Sometimes persisted operations cannot be used. E.g. if you are building an API that is used by third
party users. However, we can still apply some protection.

[Learn more about Max Depth plugin here](/docs/gateway/other-features/security/max-depth)

This can prevent malicious API users executing GraphQL operations with deeply nested selection sets.
You need to tweak the maximum depth an operation selection set is allowed to have based on your
schema and needs, as it could vary between users.

### Rate Limiting

Rate-limiting is a common practice with APIs, and with GraphQL it gets more complicated because of
the flexibility of the graph and the ability to choose what fields to query.

The [Rate Limit Plugin](/docs/gateway/other-features/security/rate-limiting) can be used to limit
access to resources by field level.

## Prevent unwanted HTTP requests

### CORS (Cross-Origin Resource Sharing) (enabled by default)

Cross-Origin Resource Sharing (CORS) is a mechanism that uses additional HTTP headers to tell
browsers to give a web application running at one origin, access to selected resources from a
different origin. A web application makes a cross-origin HTTP request when it requests a resource
that has a different origin (domain, protocol, or port) from its own.

[Learn more about CORS plugin here](/docs/gateway/other-features/security/cors)

### CSRF Prevention

Cross-Site Request Forgery (CSRF) is an attack that forces an end user to execute unwanted actions
on a web application in which they're currently authenticated.

[Learn more about CSRF Prevention plugin here](/docs/gateway/other-features/security/csrf-prevention)

## Prevent Leaking Sensitive Information

### Disable Schema Introspection

If your schema includes sensitive information that you want to hide from the outside world,
disabling the schema introspection is a possible solution. The
[Disable Introspection Plugin](/docs/gateway/other-features/security/disable-introspection) plugin
solves that in a single line of code!

### Block Field Suggestions

Field suggestions are a feature of GraphQL that allows the client to request the server to suggest
fields that can be queried. This is a very useful feature for developers using GraphQL, but it can
also be used by attackers to discover the schema of the server.

You can block field suggestions with the
[Block Field Suggestions Plugin](/docs/gateway/other-features/security/block-field-suggestions).

### Error Masking (enabled by default)

In most GraphQL servers any thrown error or rejected promise will result in the original error
leaking to the outside world. Some frameworks have custom logic for catching unexpected errors and
mapping them to an unexpected error instead. In Hive Gateway, this is enabled by default.

[Learn more about Error Masking](/docs/gateway/other-features/security/error-masking)
