What Is GraphQL?
GraphQL is a query language, as well as a server-side runtime, designed for APIs. GraphQL prioritizes providing clients with only the requested data. The goal of GraphQL is to make APIs flexible, developer-friendly and fast.
GraphQL offers an alternative to the REST architectural style – it enables developers to create requests to gather data from multiple sources using a single API call.
GraphQL lets you add or remove fields without affecting existing queries. You can construct APIs with your method of choice, and GraphQL will ensure the APIs function predictably for the clients.
This is part of our series of articles about API security.
In this article:
- How Can You Test GraphQL API Implementations?
- Components to Test in GraphQL
- GraphQL Security Testing
- GraphQL Security Testing with Bright
How Can You Test GraphQL API Implementations?
GraphQL serves as an abstraction layer located between front-end systems and backend APIs. This makes GraphQL essential for testing purposes. GraphQL queries enable access to multiple backend resources as well as aggregating data together into one meaningful response.
Backend APIs are often granular because they help create new building blocks that can be reused for multiple applications. However, this does not necessarily mean that the desired front-end actions are accomplished. GraphQL simplifies interactions with backend data. This is achieved through the use of an interface with schemas that describe system behavior. You can then get efficient data from APIs.
Each GraphQL schema maps to functions, which then make subsequent calls to your backend. The calls are made according to business logic, against databases, REST APIs and other resources required for collecting the requested data.
Next, the functions assemble all necessary information to produce a response, which retains the shape of the request. This makes it easier to identify which data relates to each element in the request.
You can also set up GraphQL to make calls to various backend services while it assembles a query response. This can reduce the overall time it takes for a user to browse through API documents in order to read and make sense of the information generated from a call.
Components to Test in GraphQL
The majority of functional GraphQL tests are optimized to ensure that the queries, mutations and schema work as expected at the front-end. There are numerous security testing tools available for running this type of testing. You can choose those that are suitable for your language, test infrastructure, platform and certain testing requirements.
EasyGraphQL, for example, is the most widely used tool for functional GraphQL testing when developing APIs with JavaScript. You can integrate it with a library, such as Mocha, and then test assertions in order to evaluate API responses—all as part of your automated test toolkit.
Here is an example of an assertion with EasyGraphQL:
t(‘should pass if the query is valid’, () => {
const validQuery = `
{
getUserByTestResult(result: 4.9) {
email
}
}
tester.test(true, validQuery)
})
Here are several types of tests you can use:
- Query tests—ensure that a certain query and its parameters return the correct response.
- Mutation tests—ensure that a certain query and its parameters successfully save data inside the database.
- Load tests—ensure that the API maintains performance (according to SLAs) even when bombarded by a large number of requests.
- Security tests—ensure that the APIs do not return any sensitive data without applying the necessary precautions.
When using GraphQL to test an external web service (e.g. GitHub V4), you should also simulate responses. This can help you avoid unnecessary usage as well as reduce test run times. In some cases, you can employ mocks and fixtures to simulate these services. However, other cases may require virtualizing services in order to analyze usage and any other metrics.
5 GraphQL Security Testing Tips
Here are some important aspects of GraphQL-based applications that should be tested to ensure they are secure.
Related content: Read our general guide to API security best practices
Consistency of Authorization Checks
A common issue when testing a GraphQL-based application is flawed authorization logic. GraphQL can help you implement data validation, but you have to handle the authentication and authorization yourself. GraphQL APIs have several layers of resolvers, which add complexity given that you need to conduct authorization checks for query-level resolvers as well as resolvers that load extra data.
One of the main types of authorization flaws that can typically be found in GraphQL APIs involves the authorization functionality being directly controlled by GraphQL API layer resolvers. To prevent exploitable flaws, you must carry out separate authorization checks in each location. This becomes more complicated as the API schema becomes more complex, with more distinct resolvers having to control access to data.
Attacks on APIs Enabled by REST Proxies
When you adapt an existing REST API for a GraphQL client, you typically start with the implementation of a new GraphQL interface, which serves as a proxy layer on top of the internal REST APIs. The API resolver converts requests to the format of the REST API, with the responses formatted so they can be understood by the client.
If requests are not safely implemented in the proxy layer, an attacker could carry out Server-Side Request Forgery (SSRF) and modify the parameters or path to the backend API. The attacker could then use the credentials of the GraphQL proxy layer to manipulate the API. This is a risk, for example, if you implement the user(id: 1) resolver in the GraphQL proxy layer—you make a GET request for /api/users/1 on the backend API.
Unvalidated Scalars
GraphQL works with scalar data for both inputs and outputs. The five standard scalars are int, string, float, bool and ID. However, you can also create custom scalars for different types of data, such as date and time.
This may be useful, but you have to be particularly careful, as you are responsible for sanitizing the user input and properly validating the data. For JavaScript-based applications, for example, you can secure your application by implementing parseLiteral and parseValue.
If you create a new scalar type using a GraphQL library, there is a higher risk of introducing vulnerabilities into your application. This may be a relatively easy way to create custom scalars, but is best avoided.
Inadequate Rate Limits
GraphQL queries can take multiple actions, so there isn’t a set amount of server resources prepared beforehand. This complexity makes it difficult to create DOS protection for GraphQL APIs, and applications become unpredictable. Rate-limiting is also difficult, because you cannot limit the number of requests in the same way for GraphQL as with a REST API for example. Even a small query can become excessively complex to execute.
Exposure of Sensitive Information Through Introspection
Hidden API endpoints can be added to provide functionalities that cannot be accessed publicly (e.g. API endpoints for handling server-to-server communications or hidden administrative functionality). Developer tools like GraphiQL IDE use hidden endpoints to retrieve the schema dynamically. For public APIs, introspection can enhance the developer experience, but this can also expose non-public information.
GraphQL Security Testing with Bright
Bright has been built from the ground up with a dev first approach to test your web applications, with a specific focus on API security testing.
With support for a wide range of API architectures, Bright tests your legacy and modern applications, including GraphQL, REST API and SOAP security.
To compliment DevOps and CI/CD, Bright empowers developers to detect and fix vulnerabilities on every build, reducing the reliance on manual testing, leveraging multiple discovery methods:
- HAR files – watch video
- OpenAPI (Swagger) files – watch video
- Postman Collections – watch video
Start detecting the technical OWASP API Top 10 and more, seamlessly integrated across your pipelines via:
- Bright Rest API
- Convenient CLI for developers
- Common DevOps tools like CircleCI, Jenkins, JIRA, GitHub, Azure DevOps, and more
Start testing your applications and APIs with a FREE Bright account. With no false positives and developer friendly remediation guidelines, security testing automation is easily achievable across your pipeline, to detect and fix security issues early and often.
Get a free Bright account and start testing your GraphQL APIs!
