Insights

Securing Access Controls in Web Applications & APIs 

Author:

Mark Rose

Over the years, Pentest has conducted hundreds, if not thousands, of assessments on web applications and APIs, helping organisations ensure their online presence is as secure as possible. During this time, we have observed many recurring issues, recently, however, we have noticed an increase in Access Control issues making their way into clients’ reports.  

To raise awareness about these issues, I have put together an overview of Access Controls, the risks they pose, and the potential consequences if these vulnerabilities are exploited.  

What Are Access Controls? 

Access Controls are essential components of web services and applications and are used by organisations to define who has access to specific resources and functionalities. This process is often referred to as session management 

Session management involves allocating a unique identifier, known as a session token, to each user. Applications typically issue session tokens automatically without requiring user interaction. It is normal for a user to receive a token upon their first interaction with the application and subsequently acquire a new token after authentication.  

As users request data, process information, and utilise functionalities, access control checks are conducted to verify that the user has permission to perform these actions. Permissions are typically assigned on an individual basis by the administrative team. In cases of self-registration, users are automatically assigned the lowest level of permissions until their access is adjusted by the administration team.  

Users can be assigned permissions in several ways, the most common being:  

  • Granular Access: Specifying exactly what actions a user is permitted to perform.
  • Role-Based Access: Grouping users into categories such as Reader, User, or Administrator. 

If a user requests an action they are not authorised to perform, they should receive an error message indicating that access is forbidden, the 403 HTTP status code is designed for this purpose. However, if proper access control checks are not implemented, users might gain access to resources or perform actions that they should not be authorised to. This leads to potential vulnerabilities.  

These vulnerabilities are classified as “Broken Access Controls” and can severely impact the confidentiality, integrity, and availability of the application and its users.  

Broken Access Controls – A Growing Risk 

As previously mentioned, there has been an uptick in Broken Access Control issues in the web applications we have tested over the last few years. This challenge has also been acknowledged by the Open Web Application Security Project (OWASP) in their OWASP Top 10 list.  

For those unfamiliar, the OWASP Top 10 represents a “broad consensus regarding the most critical security risks facing web applications” and serves as an essential reference for developers, as well as being integral to any penetration testing methodology.  

To compile the OWASP Top 10 rankings, OWASP maps Common Weakness Enumerations (CWEs) to each risk category. These CWEs detail the vulnerabilities and weaknesses that can be exploited, guiding people in identifying, mitigating, and preventing these issues.  

In the latest edition of the OWASP Top 10 published in 2021, Broken Access Controls were identified as the most critical security issue for web applications, with 34 CWEs mapped to it. This marked an increase from its previous ranking of fifth place in the 2017 review. This rise in ranking underscores the growing severity and critical nature of Broken Access Control issues. 

Impact of Broken Access Controls 

Throughout our testing experience, the following impacts have been regularly identified due to Broken Access Controls. Note: these examples have been created specifically for demonstration purposes. 

Privilege Escalation  

Privilege escalation is the process of gaining unauthorised access to another user’s content permanently by abusing application controls.  

Privilege escalation can occur in two manners: 

  • Horizontal – User to User, whereby it could be possible to compromise other user accounts/tenants. This would impact the confidentiality and integrity of their data. 
  • Vertical – User to Administrator, allowing the threat actor to control the application, data it processes, and user accounts amongst other operations. 

The following example shows the steps taken to move from a low-level tenant specific user to an administrator, designed for internal use only, allowing access data from all tenants. 

1. Authenticate into the application as a User.
2. Navigate to the Profile section of the application 

GET /MyProfile 
 [SNIPPED]  

3. Save the record whilst intercepting the request 

POST /UpdateUserProfile 
 [SNIPPED] 
  
{ 
 "accountID": "ca97f264-11d1-409e-9dbb-4ab8812d0597" 
 "firstName": "Geoffroy", 
 "lastName": "Jefferson" 
 "username": "BigGeoffyJeff", 
 "emailAddress": "contact@pentest.co.uk", 
 "userRole": "User", 
 [SNIPPED] 
 }   

4. Notice the inclusion of the userRole parameter and manipulate this to Administrator as such: 

POST /UpdateUserProfile 
 [SNIPPED] 
  
{ 
 "accountID": "ca97f264-11d1-409e-9dbb-4ab8812d0597" 
 "firstName": "Geoffroy", 
 "lastName": "Jefferson" 
 "username": "BigGeoffyJeff", 
 "emailAddress": "contact@pentest.co.uk", 
 "userRole": "Administrator", 
 [SNIPPED] 
 }  

5. Allow the server to process this and view the 200 HTTP Status Code. 

HTTP/2 200 OK 
  
{ 
 "message": "Account successfully updated" 
 }  

6. This would then grant the account Administrator privileges

You get admin - Access Control - Pentest Limited

At this point, the threat actor would be in control of the application and the data it contains. This would lead to a complete loss of confidentiality and integrity, and depending on the applications functionality, the administrator may be able to restrict access to the platform or accounts, negatively impacting the availability.  

Account Takeover via IDOR 

Account lockout is the process of impacting availability. Typically, when people think of account lockout, they associate login forms defended by mechanisms to prevent password guessing attacks. Despite this, account lockouts can happen in different manners.  

In this example, a low-level user could abuse access controls to amend details of an administrator account. These details were obtained by abusing an insecure direct object reference (IDOR) initially, demonstrating the risk.  

1. Authenticate into the application as a User
2. Action the view profile button top right of the application.
3. Observe the following request sent to the server: 

GET /User/?id=12 
 host: blah 
 [SNIPPED]  

4. Observe the following request sent to the server: 

HTTP/2 200 OK 
  
{ 
 "firstName": "Alistar", 
 "lastName": "McAllister" 
 "username": "BigAlTakesover", 
 "emailAddress": "contact@pentest.co.uk", 
 "userRole": "User", 
 [SNIPPED] 
 }  

5. Action the save button to obtain the format of the POST request as below: 

POST /User/UpdateRecord 
 host: blah 
 [SNIPPED] 
  
{ 
 "accountID": "12" 
 "firstName": "Alistar", 
 "lastName": "McAllister" 
 "username": "BigAlTakesover", 
 "emailAddress": "contact@pentest.co.uk", 
 "userRole": "User", 
 [SNIPPED] 
 }  

6. Once obtained, abuse of the IDOR could be carried out to obtain access to the user account of id 1 as such: 

GET /User/?id=1 
 host: blah 
  [SNIPPED]  

Automated tools exist that could be used to incrementally guess this parameter to compromise the confidentiality of all accounts. 

7. Observer the server response and notice this is an administrator user as defined in the userRole parameter: 

HTTP/2 200 OK 
  
{ 
 "firstName": "Top", 
 "lastName": "Dawg" 
 "username": "IAmTheCaptain", 
 "emailAddress": "admin@topdawg.co.uk", 
 "userRole": "Administrator", 
 [SNIPPED] 
 }  

8. Manually craft the request altering the email address and send the POST request using the format obtained in 5. 

POST /User/UpdateRecord 
 host: blah 
 [SNIPPED] 
  
{ 
 "accountID": "1" 
 "firstName": "Top", 
 "lastName": "Dawg" 
 "username": "IAmTheCaptain", 
 "emailAddress": "bigalcompletingtakeovers@forfun.com", 
 "userRole": "Administrator", 
 [SNIPPED] 
 }  

This data would then be processed by the server returning a 200 HTTP status code suggesting that the change was successful. To confirm, the threat actor would be able to action the forgotten your password function: 

POST /ForgottenYourPassword 
 [SNIPPED] 
  
{ 
 "email": "bigalcompletingtakeovers@forfun.com" 
}  

The email to complete the password reset process would be received by the threat actor allowing the credential set to be completely altered. This would result in complete loss of confidentiality, integrity and availability demonstrating the true risk of Broken Access Controls.  

Captain Now - Access Control - Pentest Limited

Access to Administrative Areas  

Administrative areas of applications, as the name suggests, should be restricted to users with administrative authorisation. If access to these areas were possible to any user, the impact would be dependent on what functionality was present.  

In this example, a low-level user could be able to monitor server responses to obtain web paths that would grant access to the restricted content.  

1. Authenticate into the application as a User 
2. Navigate to /admin whilst intercepting web traffic closely monitoring responses and notice the following: 

HTTP/2 200 OK 
 [SNIPPED] 
  
<br /> 
 <div class="AdminArea"> 
     <div class="SuperSecretAdminMenu"> 
     <a href="/administration/usermanagement">Users</a> 
     <a href="/administration/organisations">Organisations</a> 
     <a href="/administration/sitesettings">Site Settings</a> 
     [SNIPPED] 
 </div> 
 [SNIPPED]  

3. Continue with the navigation and observer the server finally returning a 403 HTTP status code indicating access was forbidden.
4.
Assess whether the access controls were implemented on the exact endpoints returned by navigating to one as such: 

GET /administration/organisations 
 host: blah 
 [SNIPPED]  

5. Observer the server processing the request and responding with all organisation data across the application and not just the one for the current tenant.  

HTTP/2  

200 OK 

 [SNIPPED] 

  

{  

"organisationName": "FabricatedFabrications",  

"addressFirstLine": "1337 Avenue",  

"addressSecondLine": "1337topia",  

"postCode": "TW11 1AT",  

"mainContact": "dave@fabricatedfabrications.co.uk",  

[SNIPPED]  

}  

{  

"organisationName": "FakeyMcFakeOrg",  

"addressFirstLine": "13 Faker Way",  

"addressSecondLine": "Planet Earth",  

"postCode": "AZ13 37RR",  

"mainContact": "karen@FakeyMcFakeOrg.co.uk",  

[SNIPPED] 

}  

As this data was returned, there was a loss of confidentiality. Standard users should not be able to access cross tenant data as this could result in further attacks being carried out. Further this would be a clear violation of the access control model and ultimately be a broken access control. 

Secrets - Access Control - Pentest Limited

Mitigating Access Control Issues 

Broken Access Control issues often arise due to a lack of authorisation checks. To prevent these issues, the first step is to implement appropriate checks to ensure that authenticated users have the required level of access to view or perform the actions requested.  

Authorisation checks should be conducted throughout the entire interaction, starting from the initial GET request to the final POST request. This comprehensive approach is necessary because threat actors may try to bypass application logic. If they succeed in crafting the right data, they could directly access the POST request, which could compromise the integrity of the application.  

Additionally, any excessive information not required by the client should be removed. For instance, URL endpoints should be excluded from server responses if the user does not have access to that specific area of the application. This reduction of visible information lowers the likelihood of unauthorised navigation to restricted areas. 

Another effective strategy is to remove direct object references and instead use GUIDs (Globally Unique Identifiers). By implementing GUIDs, the complexity of guessing these values is increased, decreasing the chances of unauthorised access to sensitive resources. 

When implementing access controls, additional controls should also be considered to enhance the overall security posture:  

  1. Restrict access to non-public resources by default.  
  2. Create a single access control mechanism and use it across the entire application. 
  3. Assign record ownership instead of generic read/write permissions.
  4. Log access control failures so that administrators can review them. 
  5. Implement rate limiting on any supporting APIs to prevent abuse by automated attackers. 

Conclusion 

I hope this piece has provided you with valuable insights into the significant impact that access control issues can have on the confidentiality, integrity, and availability of an application’s data, as well as the data of its users. Additionally, I hope it offers guidance on how to mitigate some of the most common issues we encounter during our testing.  

It is crucial to recognise that every application is unique and the only way to truly understand the inherent risks associated with access control is by conducting regular security reviews and assessments. At Pentest, we have been performing web application testing for over 20 years, helping our clients identify weaknesses before they can be exploited by malicious actors. 

So, if you’re looking to put your web applications and APIs to the test, why not get in touch and see how we can help provide you with the cybersecurity assurances you need. 

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.