Don’t Panic: A Developer’s Guide to Building Secure GraphQL APIs
At this year’s API Specifications Conference (ASC), Postman Developer Advocate Meenakshi Dhanani shared the dos and don’ts of designing secure GraphQL APIs. Read on for some of the highlights, and be sure to check out the full video for more details.
It’s just an API, what could go wrong?
While most of Meena’s talk was about not panicking, she did mention that you should panic if you think GraphQL is just an API. It is both an API and a query language—and this gives attackers a broader attack surface to look for and exploit vulnerabilities.
Meena used “graphql” as a keyword when searching the National Vulnerability Database (NVD) to get some statistics, and she found a notable increase in GraphQL API vulnerabilities over the past three years. She then shared a few recent examples of companies that have had to report security vulnerabilities related to their GraphQL APIs.
Meena polled the audience to see what they thought were the most common GraphQL attacks, according to the OWASP Top Ten. The responses included things like access control, broken object-level authorizations (BOLA), and denial-of-service (DoS). Meena used Postman to call the public API for the NVD to find Common Vulnerabilities and Exposures (CVEs) that included “graphql” as a keyword and used the results to look for patterns among the vulnerabilities.
Check out the word cloud below that Meena generated using this search, or generate it yourself in the GraphQL Security 101 public workspace. Read on to learn more about the common attack types you need to consider when you design your GraphQL APIs.
Some of the most common attacks made against GraphQL are related to access control. Most queries in the GraphQL schema require authentication or a description of what users can access. A resolver, which also houses the business logic, responds to GraphQL queries on the backend, and frequently, it will also call other functions that are related to the business logic. Meena came across a lot of examples where developers forgot to authenticate all queries because they had tightly coupled the authentication into the specific resolvers.
To protect your GraphQL APIs against access control attacks, here’s what you need to know:
- Authentication: Queries can be authenticated at a layer before the resolver using the context in GraphQL that runs for each query and can provide the resolver with the user logged in.
- Authorization: If there are no safeguards in place, some types and fields can be accessible to users who don’t have the correct role. Add role checks in the resolvers, and maintain an allowlist for queries and roles.
DoS is another of the most common GraphQL attacks.
To protect your GraphQL APIs against DoS attacks, here’s what you need to know:
- Nested recursive querying: Because GraphQL types can reference each other, an attacker can use recursion to build a circular query that brings down the server. Prevent these attacks with max depth checks.
- Batch attack: GraphQL queries support batching because they are executed sequentially, and intensive queries can cause DoS attacks. Prevent these attacks by putting rate limits in place, especially for resource-intensive functions.
- Aliased queries: Even if batching is disabled, attackers can use aliases to build queries that run repeatedly and cause DoS. Run a query cost analysis to decide whether or not to run the query.
Information disclosure attacks are another frequent strategy used against GraphQL APIs.
To protect your GraphQL APIs against information disclosure attacks, here’s what you need to know:
- GraphQL introspection: The
_schemaquery allows you to learn about all of the fields and types in a schema, which could expose sensitive fields like user IDs, roles, or passwords. Prevent these attacks by disabling introspection in production, as well as enabling authentication and authorization for incoming requests.
- Error suggestions: If you query a schema with a typo in the field name, the GraphQL error message suggests the name of a similar field.
- Server-side request forgery: Mutation queries accept input. If the input is malicious, it could perform an unwanted action on an internal resource. Prevent these attacks by sanitizing input before execution, as you would for any other API.
Injection attacks against GraphQL APIs are also common.
To protect your GraphQL APIs against injection attacks, here’s what you need to know:
- SQL injection: Queries accept input that can include raw SQL. Prevent these attacks either by accepting only prepared statements or sanitizing the input you receive.
- Log injection: Logs can be spoofed by providing incorrect operation names for a query or mutation. Prevent this by enforcing an allowlist for operation names.
Wrapping it up
If you have GraphQL APIs in production, make sure you’re aware of these vulnerabilities so that you can protect yourself against them. Everyone makes mistakes—and one person’s mistake can bring a server down. Meena’s closing recommendation? Make users ask for permission rather than forgiveness.
Watch the full presentation
Learn more about GraphQL security
Meena shared some additional resources that can help you secure your GraphQL APIs:
- If you’re new to GraphQL, check out this introduction to GraphQL security video
- Try out some of the attacks in the Damn Vulnerable GraphQL Application Docker image
- See some examples of attack requests in the GraphQL Security 101 public workspace
Technical review by Meenakshi Dhanani.