Mitigate OWASP A01 2021 Broken Access Control Web Security Tips

Hello Everyone,

I hope you are doing well. Today in this article, We will review one of OWASP vulnerabilities, A01:2021-Broken Access Control, and its remedy and best code practice to enhance the security of web applications.

Explanation

Broken Access Control is one of the most common web application vulnerabilities listed in the OWASP Top 10. It occurs when a user can perform actions and access resources that they are not authorized to access, often due to insufficient enforcement of access control policies.

Access control involves restricting access to resources based on user permissions. Broken access control happens when an attacker can bypass these restrictions due to implementation flaws, misconfigurations, or design issues. This can allow attackers to view or modify unauthorized data, perform unauthorized actions, and generally escalate their privileges within an application.

Types of Broken Access Control

  • Horizontal Privilege Escalation: This occurs when users can access data or perform actions pertinent to other users at the same privilege level. For instance, one user is editing the profile information of another user.
  • Vertical Privilege Escalation: This type of vulnerability is seen when users can elevate their privileges and perform actions reserved for users with more rights, such as administrative actions.
  • Bypassing Access Control Checks: This is achieved through modifying the URL, internal application state, or the HTML page or simply using a custom API attack tool, where the attacker manipulates these elements to access unauthorized functionalities.
  • Insecure Direct Object References (IDOR): This happens when an application uses user-supplied input to access objects directly, such as database records or files.
  • Missing Function Level Access Control: Sometimes, the front end correctly restricts functionalities, but the backend services remain unprotected, and direct requests to them could compromise security.

1. Horizontal Privilege Escalation

Vulnerable Code

[HttpGet]
[Route("api/document/get")]
public IActionResult GetDocument(int documentId)
{
    var document = _dbContext.Documents.FirstOrDefault(doc => doc.DocumentId == documentId);
    
    if (document != null)
    {
        return Ok(document);
    }
    
    return NotFound();
}

In the above code, any authenticated user can access any document just by knowing its document ID.

Secure Code

[HttpGet]
[Route("api/document/get")]
public IActionResult GetDocument(int documentId)
{
    var userId = User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
    
    var document = _dbContext.Documents.FirstOrDefault(doc => 
        doc.DocumentId == documentId && doc.OwnerId == userId);

    if (document != null)
    {
        return Ok(document);
    }
    
    return NotFound();
}

Now, users can only access documents they own.

2. Vertical Privilege Escalation

Vulnerable Code

[HttpPost]
[Route("api/user/promote")]
public IActionResult PromoteUser(int userId)
{
    var user = _dbContext.Users.Find(userId);
    
    if (user != null)
    {
        user.Role = "Admin";
        _dbContext.SaveChanges();
        return Ok();
    }
    
    return NotFound();
}

Any authenticated user can promote any user to an admin role.

Secure Code

[HttpPost]
[Route("api/user/promote")]
[Authorize(Roles = "Admin")]
public IActionResult PromoteUser(int userId)
{
    var user = _dbContext.Users.Find(userId);
    
    if (user != null)
    {
        user.Role = "Admin";
        _dbContext.SaveChanges();
        return Ok();
    }
    
    return NotFound();
}

The [Authorize(Roles = "Admin")] ensures that only users with an "Admin" role can promote others to admin status.

3. Bypassing Access Control Checks

Vulnerable Code

[HttpGet]
[Route("api/settings/get")]
public IActionResult GetSettings()
{
    // Suppose sensitive settings should be admin-only
    return Ok(_dbContext.Settings.First());
}

Secure Code

[HttpGet]
[Route("api/settings/get")]
[Authorize(Roles = "Admin")]
public IActionResult GetSettings()
{
    return Ok(_dbContext.Settings.First());
}

The use of [Authorize(Roles = "Admin")] prevents non-admin users from accessing sensitive settings.

4. Insecure Direct Object References (IDOR)

Vulnerable Code

[HttpGet]
[Route("api/profile/view")]
public IActionResult ViewProfile(int userId)
{
    var profile = _dbContext.UserProfiles.FirstOrDefault(p => p.UserId == userId);
    
    if (profile != null)
    {
        return Ok(profile);
    }
    
    return NotFound();
}

Users can view any user's profile just by changing the user ID.

Secure Code

[HttpGet]
[Route("api/profile/view")]
public IActionResult ViewProfile(int userId)
{
    var authenticatedUserId = int.Parse(User.Identity.GetUserId());
    
    if (userId != authenticatedUserId)
    {
        return Unauthorized();
    }
    
    var profile = _dbContext.UserProfiles.FirstOrDefault(p => p.UserId == userId);
    
    if (profile != null)
    {
        return Ok(profile);
    }
    
    return NotFound();
}

Now, users are restricted to only viewing their profile.

5. Missing Function Level Access Control

Vulnerable Code

[HttpGet]
[Route("api/data/export")]
public IActionResult ExportData()
{
    // Export sensitive data
    return Ok(_dbContext.SensitiveData.ToList());
}

There's no control over who can export sensitive data.

Secure Code

[HttpGet]
[Route("api/data/export")]
[Authorize(Roles = "Admin")]
public IActionResult ExportData()
{
    return Ok(_dbContext.SensitiveData.ToList());
}

Only admins can now export sensitive data.

Each of these examples illustrates the importance of proper authorization in web applications to protect resources from unauthorized access. Always ensure that both the backend and frontend enforce access controls correctly. Regular audits and security tests are also vital to maintain a secure application.

Remedies and Code Practices to Prevent Broken Access Control

  • Ensure Proper Configuration: Implement and regularly update access control rules in security configurations - never leave this to default or 'AUTO' settings.
  • Use Principle of Least Privilege: Users should be provided with the minimum level of access necessary. For instance, separate user roles and restrict the sensitive information/actions strictly to higher roles.
  • Implement Robust Authentication and Authorization Checks: Use well-established frameworks (for example, ASP.NET's Identity framework) to manage user authentication and authorization consistently across the application.
  • Provide Secure Direct Object References: Use indirect object references like GUIDs or securely hashed details that are not guessable.

Conclusion

Broken access control is a critical and prevalent security vulnerability that exposes sensitive data and functionality to unauthorized users, leading to significant security risks. Proper mitigation involves implementing robust access control mechanisms such as RBAC (Role-Based Access Control) and ABAC (Attribute-Based Access Control), adopting secure coding practices, and ensuring consistent enforcement across the application. Regular security audits, user education, and compliance with legal and regulatory standards are essential to prevent and manage these vulnerabilities effectively. Proactive prevention and response strategies are crucial for maintaining the security and trustworthiness of software applications.


Similar Articles