Overview
The implementation of GraphQL in enterprise systems has grown rapidly. A recent report from Gartner predicted that at least 50% of enterprises will be implementing GraphQL in their production environments by the end of the calendar year. With its increasing adoption, correctly accounting for the security of GraphQL APIs becomes increasingly pertinent. Although the structure of GraphQL APIs appears to differ from normal APIs, standard security considerations such as the OWASP Top Ten still play a large role.
Recently our team was assessing a financial application that implemented a GraphQL API. The API was used to authenticate users, evaluate permissions, and authorize access to the application’s sensitive components. During the assessment we found an attack vector that allowed us to access the whole application with full administrative privileges. Broken authentication and authorization controls, such as the one we identified, have been on the OWASP Top Ten since its inception in 2003.
Identifying authorization protocols and privilege escalation
The process of identifying and exploiting this vulnerability began when trying to access the web-application’s administrative panel. The panel allowed us to edit application metadata, and exfiltrate sensitive financial data. However, we were only allowed to edit metadata or exfiltrate data if we were identified as having administrative privileges. Without these permissions, users attempting to edit or export data were greeted with an ‘Access Denied’ message as seen in Figure 1 below.
![](https://www.praetorian.com/wp-content/uploads/2024/07/admin-access-denied.png)
Figure 1: Editable metadata was categorized by groups, such as ‘Organization’, ‘Run frequency’, and ‘Use case type’. Non administrative users attempting to view the data had their request denied.
When we proxied, the requests sent while accessing the admin panel through Burp Suite, we noticed a GraphQL query called brassCheckAccess sent to the applications GraphQL endpoint. Its inputs were the authenticated user’s username and the id of ABC_Admin. It returned the ‘is_authorized’ value or true or false if the user was authorized to use the ABC_Admin id. As seen in Figure 2 below, our test user zatezala, was not authorized to use the role. Subsequently he could not access any of the admin panel’s functionality.
![](https://www.praetorian.com/wp-content/uploads/2024/07/Check-Access-1.png)
Figure 2: User zatezala is denied authorization.
We decided to enumerate administrative usernames by launching an attack via BurpSuite’s Intruder. As seen in the Figure 3 below, the username variable was set as a payload in Intruder. We constructed a list of potential administrative usernames and used Intruder to execute a sniper attack. This gave us a list of usernames that returned an ‘is_authorized’ value of ‘true’ for the brassCheckAccess query.
![](https://www.praetorian.com/wp-content/uploads/2024/07/Intruder-Setup.png)
Figure 3: Setting up the intruder attack.
By intercepting a request to access the admin panel sent by test user ‘zatezala’ and replacing his username with a username authorized to assume the ‘ABC_Admin’ role, we could access the admin panel with administrative privileges.
![](https://www.praetorian.com/wp-content/uploads/2024/07/admin-access-granted.png)
Figure 4: Accessing the admin panel as an administrator.
Recommendation
To fix this vulnerability, the username supplied to the brassCheckAccess function should be validated using the requesting user’s cookie or session token. Although broken access control vulnerabilities can take many forms such as Insecure Direct Object References (IDORs) or an access control bypass they most often result from the improper sanitization and validation of user supplied input. All user supplied input such as HTML form data, and URL query parameters should be validated by back-end systems. Access should be blocked by default and only granted after verification. Directive constraints, middleware, and the implementation of customized scalars can play a critical role in sanitizing and validating the user supplied data used by GraphQL.
Conclusion
In this article, we discussed a privilege escalation vulnerability we identified in a GraphQL API. Broken authentication and broken authorization such as the one we found have been part of the OWASP Top Ten list for over twenty years. Although this attack path might seem relatively basic, sometimes having an advanced security practice just means doing the basics well. Even when implementing new tools and technologies, preventing those “evergreen” vulnerabilities that seem to re-occur year after year is paramount.
References
7 Key Insights in GraphQL trends
Gartner Report
Describing Broken Access Controls
Validating User Supplied Data In GraphQL
Share via: