GraphQL APIs are gaining popularity among API developers with the flexibility it provides to request for the exact data that a user wants and to receive only that. Especially for consumer facing applications backed by APIs, frontend developers love the idea of GraphQL over REST with its ability to fetch the exact data and to fetch multiple resources in a single request. Along with these dynamic queries and added advantages it also demands tightened API security. Therefore, it is important to understand the various vulnerabilities associated and align the API security mechanisms in order to get the best out of GraphQL APIs.This article highlights the various security mechanisms that API developers should consider and discuss the possible scenarios where each mechanism is applicable.
GraphQL, similar to REST, is another way of requesting data through an API. However unlike REST, GraphQL does not under or over fetch data. This provides more flexibility and freedom to the client to receive the exact information that is required. [1] is a quick reference to understand how GraphQL works in comparison to REST. If an organization is strategizing to expose their APIs with GraphQL, it is important to understand that with great power comes great responsibilities. This is to say that while providing the enhanced querying flexibility to the consumers , it is even more important to initiate the right level of security to protect your APIs and data.
There are 3 main aspects when looking at API security; authentication, authorization and threat protection where the APIs are secured against any potential attacks.
Authentication layers in GraphQL can be implemented with common patterns such as OAuth. Ranging from the use of JWT tokens which are passed in the authorization header can be checked at the context level of each query. This can be further strengthened with an authorization implementation by delegating any data access logic to the business logic layer and not handling it in the GraphQL implementation. Use of OAuth scopes would be a good mechanism to handle access control. However, GraphQL developers are usually left on their own to implement the authentication and authorization methods for the APIs.
WSO2 API Manager along with the support to create GraphQL APIs, provides out of the box API security as well. As depicted below, API creators can enable/disable API security ( OAuth) and role based access control by specifying scopes to each GraphQL operation independently.
With the flexibility of GraphQL, the API consumers have the freedom to come up with various queries which can result in larger complex queries making the APIs vulnerable. Therefore, it is quite important to have defense mechanisms to protect the APIs. A GraphQL query can take arbitrarily many actions,which means most of your server resources could be consumed. Therefore, simply limiting the number of requests is not a sufficient way of throttling GraphQL APIs. There are three common approaches to this which are throttling based on server timeouts, maximum query depth and the query complexity. Based on the type of APIs (internal/external) and the use-cases you could use a mix of these as required.
For example, throttling based on server timeouts(where a maximum time limit is set for the query execution) is a good approach, if your GraphQL APIs are internal facing where there is good understanding on the various use-cases/usage of the API and such knowledge can be easily communicated to the consumers . If your APIs are consumed by external consumers they might not know how long their queries may take to execute until it is executed at least once hence communicating server timeouts and getting the users to honour it might not work.
Setting a maximum query depth is also a good approach however, this method alone will not mitigate all the risks. For example a query requesting a large number of nodes in the root level will exhaust the server but will not be blocked in this method. Finally throttling based on query complexity, can be used where you define complexity(each field/argument will have a complexity figure assigned) for a query and come up with a maximum cost for a given query to throttle from. For example, if a query complexity is 2 and the maximum cost/bucket size is set to 8 a given client can only invoke that query 4 times before they are throttled out.
In WSO2 API Manager when creating throttling policies for GraphQL APIs, the user can set query depth limit and query complexity limit as below ,adhering to the above strategies.
Overall it is quite important to understand your API community and the various API security methods that you can/should implement so that you can reap the benefits of GraphQL APIs.
[1] https://himashaguruge.medium.com/understanding-graphql-as-a-restful-api-developer-4e9f2dc5b281