Insights

An Insight Into GraphQL Vulnerabilities 

Author:

Nour Alomary

Over the last few years, we’ve seen the use of GraphQL within applications and APIs steadily rising within our testing engagements. However, the use of GraphQL brings with it a number of potential security vulnerabilities. 

In this insight, I look at the common issues we find associated with GraphQL during testing, the risks and provide my recommendations to mitigate/secure against such risks. 

Due to the confidentiality of the projects, no examples will be provided, however an overview of the issues will be covered. 

But first, for those unaware, what is GraphQL? For those who do know, feel free to skip ahead. 

What is GraphQL and why are developers using it? 

GraphQL is a query language for APIs and has recently been used as an alternative to REST due to its features and flexibility.  

Originally developed by Facebook and later open-sourced. Its use has been widely adopted by companies such as Meta, Coursera, GitHub, AWS, IBM and Microsoft to name a few. 

As mentioned, we have noticed an increase in the number of clients who now use this technology within their applications, however it isn’t just our clients, there are various reports that show the trend is growing. But why are developers starting to utilise GraphQL more and more in their applications? There are a number of potential reasons: 

  • Allowing Application clients to have greater control over the data they receive and as such, they are more stable and do not have to handle unnecessary data. 
  • A single endpoint is used by application clients to interact with the API.
  • It eliminates the need for maintaining different API versions.
  • It helps improve speed as customisable data can be requested in a single request 

Common GraphQL attack vectors and how to protect applications against them 


1. Route Change
 

Often, opportunistic attackers will look to enumerate the files and directories on popular sites, this is usually done by sending requests using common file and folder names and observing the response sent back. In these responses, an application may inadvertently expose that the application is utilising GraphQL. Additionally, when directly browsing to the URL, the server may be insecurely configured to allow Introspection. We’ll cover this next. 

Impact 

Having an easily guessable route to the GraphQL endpoint allows unauthenticated attackers to access and interact with the API. In using a non-default route name, an attacker may need to invest additional time into enumeration or attempt to gain authenticated access to the application.  
While this would not thwart a dedicated attacker, it can help deter opportunistic ones. 

Mitigation 

To protect against this risk, a protection mechanism could be used to minimise exposure to opportunistic attackers through changing the URL route used by GraphQL to a non-standard name or phrase. For example, using a different name instead of the default “/graphql”. 

2. Introspection 

Introspection is a feature which allows users to interact with the GraphQL API. This is done by querying the __schema field, allowing users to learn more about the structure of the API implemented. 

An example query can be seen below: 

{ 
  __schema { 
    types { 
      name 
    } 
  } 
}  

Different introspection queries can be used to query the API, these would return the desired outcome. Often, introspection is left enabled within environments, both in live and pre-production and queries can be executed without authentication.  

Impact 

The impact of introspection ranges from a low risk all the way to a critical vulnerability depending on other factors, such as the presence of other vulnerabilities or misconfigurations.  

Examples include allowing an unauthenticated attacker to query the schema through introspection, identifying a query which would allow them to view application user information, this could include sensitive information such as Personally Identifiable Information (PII) or possibly financial or medical data.  

Another example could include the use of information exposed to identify mutations which would allow the attacker to modify, delete or create new data within the application.  

This could easily have been mitigated by disabling introspection which would make it difficult for opportunistic attackers to exploit. 

In some instances, graphical interfaces, such as GraphiQL can be found enabled on the server. Introspection does not necessarily rely on these graphical interfaces. While it provides an intuitive interface for an attacker to utilise, the output from an introspection query can be used with external tools which would provide additional features and functionality to allow the user to easily understand the structure of the application’s schema.

Mitigation 

To protect against this vulnerability, it is recommended that Introspection and accompanying graphical interfaces are disabled in all externally accessible environments. 

Securing only the live environment is not sufficient, this should also be done on pre-production environments that are accessible. Dedicated attackers may choose to target the pre-production environments as they are generally less secure compared to a production environment and may contain newer updates and features which may have vulnerabilities.  

While some GraphQL implementations now offer disabling Introspection by default (such as Apollo and fastify-gql), it is recommended that clients confirm this or modify the configuration if required in their own implementation.   

3. Verbose Error Messages  

Verbose error messages can be a very useful tool when targeting applications. Their presence could direct the attacker to which technologies, frameworks and versions are in use.  

Impact 

This would allow them to narrow down the potential targets as well as help focus their efforts on specific things.  

For example, if through introspection, an attacker identifies an unauthenticated query or mutation, a verbose error message containing SQL information could disclose the database technology used as well as information about the tables and fields. Such information could allow the attacker to create the necessary queries to exfiltrate data.  

Mitigation 

To mitigate against this, the application must use generic error messages as opposed to detailed error messages containing the exact cause of the error or stack trace information. If detailed information is necessary for debug or support purposes, consider using unique identifiers and their corresponding values in internal log files. Also ensure debug more is disabled. 

This would allow the developers to track the error messages without exposing the specific details to external users.  

4. Injection Attacks  

Generally, in web applications, lack of input sanitisation allows attackers to inject malicious payloads which would execute when processed or displayed in the web page. It is vital that all user input is considered untrusted and treated as such by ensuring the necessary sanitisation is carried out depending on the context before processing on the server to minimise these vulnerabilities. Client-side sanitisation is not sufficient as there are usually ways to circumvent them. 

GraphQL applications are not immune to these types of vulnerabilities and remediation should be carried out to ensure that they are not left vulnerable.  

Impact 

A graphQL endpoint could be vulnerable to SQL Injection or Cross-Site Scripting. Just to name a few. This is based on how the application was built to handle user input. If no or insufficient user input sanitisation and other defensive coding strategies are used, an application could be vulnerable. Depending on the vulnerability present, an attacker may be able to read or modify data from the database or execute malicious JavaScript payloads. 

Mitigation 

Mitigating against this requires consistent input validation, sanitisation and encoding to ensure all user input is considered untrusted and is dealt with according to the context.

5. Access Control  

Modern dynamic applications allow users to input and store user data. This is done through GraphQL using mutations. Mutations are queries that modify the data and carry out CRUD operations. (adding new, modifying or deleting existing objects) 

This is where introspection is very useful to an attacker as it will provide them with information about the possible mutations and the fields required as well as any properties/fields which can be modified without being intended to. (An attacker could create their own mutations which would bypass the intended actions.) 

Impact 

This manifests in a number of ways, the first being the API does not adequately check the user authorisation before allowing them to access or modify data. This would compromise the confidentiality and integrity and availability of the data. This depends on the endpoint in question and the data it exposes. 

Another example of this is when authorisation checks are not implemented and allow a lower privileged user to access functionality which should only be accessible to users with a higher role/privilege or administrators. This would allow users to potentially compromise the data and, in some cases, compromise the entire application and beyond.  

Mitigation 

These vulnerabilities could easily be mitigated using secure development practices as well as regular penetration testing to ensure that the mechanisms in place are sufficient and working as expected. Additional testing is recommended when new functionality is implemented or when major code changes are undertaken.  

6. DoS & Batching Attacks 


Denial of Service 
 

DoS attacks may be possible within the API if the application does not protect against them. This is usually done when the application allows users to create queries which result in generating large responses (content of through intensive server-side processes/actions). This could result in the server resource exhaustion and denial of service. 

Such an attack would impact the availability of the application and may also result in financial repercussions. 

Impact 

Denial of Service vulnerabilities can have a significant impact on the availability of an application. This could translate to negative financial or user experience to the organisation.  

Mitigation 

The impact of this vulnerability could be mitigated by following general security best practices such as implementing rate limiting and a limit on the query size. And in the specific case of GraphQL best practice, limiting the query depth to prevent Denial of Service.  

Batching Attacks 

Batching refers to executing multiple queries with a single request. In GraphQL this can be done by sending multiple queries in the same request as shown below: 

[ 
    { 
        "query":"{user(username: \"admin\") {uuid}}" 
    }, 
    { 
        "query":"{post(id: 1) {title}}" 
    } 
]  

The response will contain the results for both queries, one after the other.  

Impact 

While batching is not a security vulnerability, but a toggleable feature, it can be abused in certain scenarios. 

For example, it can allow attackers to perform brute-force attacks by including multiple login queries in a single request. Effectively allowing to bypass any rate limiting or similar protection mechanisms. 

Mitigation 

The recommended mitigation is to implement limits on the requests at the code level. There are a number of ways to achieve this. One such method is to implement rate limiting at a code level to track how many times different object instances have been requested by a user. This would allow for blocking should they exceed the reasonably allowed limit. This would include batched requests. 

Other options exist and should be considered; however, the implementation may require a custom solution.  

Securing GraphQL within your APIs 

Hopefully this insight has given you an awareness into the common vulnerabilities we see when it comes to GraphQL within our testing, the impact these could have on your organisation and has given you some general advice on how to mitigate against these before they can be exploited by malicious attackers. 

Further information can be found in OWASPs cheat sheet, which covers the issues above and provides some technology specific recommendations. 

Whilst these resources are a good frame of reference when looking to secure your GraphQL implementations, there is no guarantee that the measures put in place will be robust. That’s why regular security testing, such as web app penetration testing, is essential. 

So, if you’re concerned about potential GraphQL vulnerabilities, or any aspect of your web applications for that matter, get in touch and see how we can help provide the security assurance you need. 

Sources: 

Looking for more than just a test provider?

Get in touch with our team and find out how our tailored services can provide you with the cybersecurity confidence you need.