Tenant isolation, access control and account takeover (ATO) in GraphQL

If you have ever worked with graphQL, you must know that checking that access control is implemented correctly is a nightmare. Access control is restricting access to a specific resource. In graphQL, you must check that every link (between an object and an object or between a query and an object) has implemented proper access control.
This, of course, is not an easy task. When it comes to big graphQL schema, making sure of that is like finding a needle in a haystack; nearly impossible. That is why developers need a tool to check that for them. This is where Escape automated tool comes in.
Escape automated tool is an automated penetration testing tool that checks that your graphQL application is secured. One of the many things that it checks for is that you have implemented proper access control, and it does it thanks to the four checks.
Private Data
Private data is a check made to ensure that a specific user can access some data. In other words, it is a check to see if access control has been implemented on the data level in the graphQL schema. To implement it in Escape, you need to add some options to the configuration file of the scan. A template of the configuration can be found below.
{
"checks": {
"access_control/private_data": {
"parameters": {
"user1": [],
"user2": [
"pmarleau@gontoz.tech",
"lucas@datasentry.no",
"-----BEGIN RSA PRIVATE KEY-----"
]
}
}
}
}
As seen above, it is important to notice that to use these access control scans, you usually have to provide the scanner with more than one user. In the case above, we can see that we want to check that user 2
cannot access any data from the list of things seen in the configuration. If the user has access to those data, a security alert will be seen.

In addition to seeing from where the access control has not been implemented, you can see that there is a remediation section where the tool tells you how to solve the problem and in addition to documentation pages from graphQL engine providers like Apollo.
Private Field
Similar to the private data check, the private field check is access control implemented on the field level. To implement private field access control, you need to add some options to the configuration file of the scan. A template of the configuration can be found below.
{
"checks": {
"access_control/private_fields": {
"parameters": {
"user1": {
"User": [
"email"
],
"Query": [
"debug"
],
"CreditCard": [
"number",
"cvv",
"belong_to"
]
},
"user2": {
"query": [
"userTransactions"
],
"mutation": [
"newTransaction"
],
"Transaction": [
"id"
]
}
}
}
}
}
Unlike private data, where you only provide the data that the specific user shouldn't be allowed to access, in the private field check, you must provide the object and the field in the object that the user shouldn't be allowed to access. Note that, since queries are fields, you can provide the queries the user cannot access, as seen above. Once the tool finished scanning, you will see which of these fields the user could access, and you will also see the remediations to implement to solve the problem.

Tenant Isolation
The final access control check that Escape provides is tenant isolation. Tenant Isolation checks whether the same instance of an object is accessible by more than one user. Consider that your application is a bank, and you want to use graphQL for the web application. Now, do you want one client to see another client's account or see another client's credit cards? No! You want each client to be isolated from another; this is tenant isolation.
To implement tenant isolation in Escape, you need to add some options to the configuration file of the scan. A template of the configuration can be found below.
{
"checks": {
"access_control/tenant_isolation": {
"parameters": {
"objects": [
"User"
],
"scalars": {
"query": [
"me",
"user"
],
"Account": [
"id",
"amount",
"owner"
]
}
}
}
}
}
In the configuration, you don't need to mention what a user can or cannot access. What you need to do is to input what objects, queries, and fields should be isolated. After running the scanner, you can see which objects and fields you provided had the same instance accessed by two users. As well as the two previous security checks, you will be able to see the remediations to solve this problem with the result of the scan.

Data Leaks
In addition to the security checks that ensure proper access control has been implemented, Escape security tool also checks for data leaks in the graphQL endpoint. These leaks cannot be configured. In other words, the tool searches for predefined leaks that might hurt the user in case they were leaked. These security leaks include private SSH keys, credit card info, IBAN, social security numbers, etc...
When the scanner finishes scanning your graphQL endpoint, you can see these data leaks in the Sensitive Data
section of the tool, as seen below.

Conclusion
Checking if access control is appropriately implemented in a huge graphQL application was hard. Still, with this guide that helps you understand how to do that with Escape, you will be able to secure your graphQL endpoint instantly. In case of any more questions regarding configuration and other Escape tool-related concerns, you can check the documentation page.