GraphQL is a query language and runtime for APIs. It was developed by Facebook in 2012 and released as an open-source project in 2015. In the dynamic landscape of modern web development, GraphQL has emerged as a powerful tool for crafting efficient and flexible APIs compared to traditional REST APIs. Its ability to allow clients to precisely request the data they need, has revolutionized the way applications interact with backend services and managed to address many of the challenges and limitations associated with traditional REST APIs.
Using GraphQL offers a security advantage because its design mandates a schema. This schema prevents unwanted data from being sent to the API. However, just like other APIs, clients can still send data that might exploit back-end vulnerabilities. Hence, it's crucial to monitor API calls and prevent any that appear harmful.
In this blog we will explain how to protect GraphQL applications effectively without any change to the protected application, using open-appsec.
open-appsec builds on machine learning to provide pre-emptive web app & API threat protection against OWASP-Top-10 and zero-day attacks. It can be deployed as add-on to Kubernetes Ingress, NGINX, Envoy, Kong and API Gateways.
open-oppsec simplifies maintenance as there is no threat signature upkeep and exception handling, like common in many WAF solutions.
Securing GraphQL-based applications
To protect your APIs you need to deploy open-appsec either as a reverse proxy add-on or add-on to Kubernetes Ingress or Kong API Gateway. The different deployment options are explained the documentation, in these video Tutorials and in the Playgrounds - free virtual labs.
Here are some of the deployment option available:
Protecting GraphQL API
Protection against malicious payloads in GraphQL API request is done automatically and by default simply by configuring configuring an API asset.
You can do the setup in different ways:
Using Web Interface in the open-appsec portal
Using local configuration files
Using Kubernetes CRDs
Follow the documentation for complete instructions.
Configure HTTP Request BODY logging
To monitor API related events, you may want to turn on the HTTP Request Body logging feature.
To do that navigate to the Triggers Menu and edit the trigger object used in your API asset. It is also possible to create a new trigger object specifically tailored to the GraphQL web asset's requirements with additional changes.
In the trigger object, ensure that the “Request Body” option is selected and enforce the policy.
If using Kubernetes CRD, change the value of "request-body" from "false" to "true" in the relevant Log Trigger CRD. See here for more details on changing CRDs.
Monitoring API Related Events
When examining traffic logs, it's crucial to first identify the which API is used.
With GraphQL-based APIs, the API details are enclosed within a parameter named "query" within the HTTP request body. This parameter includes both the GraphQL API's name and its type. The type can be either a query, indicating a read-only API, or a mutation, for adding/updating/deleting data.
For clarity, it's important to highlight that in both cases, the parameter inside the HTTP request body that contains the API is designated as the string “query”, regardless of whether the API functions as a query or a mutation.
Examples of the content the “query” parameter can include:
Here is an example of how it will look in the Event:
Exceptions and Custom Rules
In some cases you may want to define an Exception or a Custom Rule. The most common use case of exception configuration is when an event is issued and after checking it you decide that it should not be blocked by the open-appsec engine.
When configuring an exception for a specific GraphQL API, instead of using the URI as you would do for REST API to specify the API, a different exception query is needed. The exception should look for a parameter name (within the request body) called “query” as it includes the exact GraphQL API name, as well as its type (read-only query, or a mutation that adds/deletes/updates the data).
In the context of GraphQL, The HTTP URI and HTTP Method exception query keys lose relevance, as they all share the same value for all GraphQL requests - usually, a POST method with a URI ending with “/graphql”.
Instead, an exception for a specific API should contain:
- The key parameter name and the value “query”
- The key parameter value and, as the value, a regular expression encapsulating the API name.
To set up an exception in the open-appsec UI, navigate to the asset representing the GraphQL API server, and access the “Custom Rules and Exceptions” tab. Proceed to define the exception rules as explained. It should look like this:
Make sure to enforce the policy when you complete the policy changes.
Certainly, when needed, you have the flexibility to create more elaborate regular expressions. Such regular expressions can match the specific usage of a particular GraphQL API.
Protecting against API attacks is crucial for ensuring the security, integrity, and availability of web services and applications. APIs serve as the gateways for data exchange and functionality, enabling various systems to interact with each other.
However, they are also vulnerable points that hackers can exploit to gain unauthorized access, steal sensitive data, or disrupt services. A compromised API can lead to a cascade of security incidents affecting not just the API itself but also the systems and users that depend on it. Therefore, implementing robust security measures such as rate limiting, data validation, and authentication is essential for safeguarding APIs and maintaining the trust of users and stakeholders.
With open-appsec, protection against malicious payloads in GraphQL API request is done automatically and by default simply by configuring configuring an API asset. It is recommend to turn on HTTP Request Body Logging so you have the full context of the event.
open-appsec is an open-source project that builds on machine learning to provide pre-emptive web app & API threat protection against OWASP-Top-10 and zero-day attacks. It simplifies maintenance as there is no threat signature upkeep and exception handling, like common in many WAF solutions.