Secure coding

How To Mitigate Least Privilege Vulnerabilities

November 17, 2020 by Srinivas

Introduction

In the previous articles about Least Privilege Vulnerabilities, we discussed why privileges are important to be controlled and how they can be abused by malicious users or attackers. There are several best practices that can be followed to avoid such vulnerabilities when developing software. This article discusses how privilege escalation vulnerabilities can be avoided in web applications by implementing Role Based Access Controls.

Securing web applications from least privilege vulnerabilities

Case 1: 

Let us begin with the following code snippet from the view profile feature of an application.

if(!isset($_SESSION[‘user_loggedin’]))

{

    header(‘Location: index.php’);

}

if(isset($_POST[‘button’]))

{   

$username = $_POST[‘user’]; 

$query = “SELECT * FROM customer WHERE username='”.$username.”‘ “;

}

else{

//do something

}

 

This code snippet shows that the application allows a user to view his profile and the username is passed as a post parameter. This username is then passed to an SQL query to retrieve the user information, which will be displayed back to the user. There are two security vulnerabilities here. 

  1. SQL Injection due to user input appended to an SQL query without validation
  2. Insecure Direct Object Reference due to missing access controls

SQL Injection being out of scope for this article, let’s understand missing access controls. In the example shown above, the object reference is the key, which is used to fetch records from the database. Since this key is visible to anyone accessing the feature with a valid session, a malicious user can simply tamper the username and submit another user’s username and the application has no way to verify who submitted the request since the application is only checking if the user has a valid session or not. These types of vulnerabilities are known as Insecure Direct Object References. The real problem with Insecure Direct Object References is lack of proper access controls. Developers often assume that URL is being passed to the server through POST or hidden form fields may not be tampered. Thus they don’t perform any additional validation on these parameters at the server side. In the above example, the application is reading the username from the session variable and storing it in a hidden form field. It is then sent to the server when the user wants to view the profile information.

Now let us go through the following code.

if(!isset($_SESSION[‘user_loggedin’]))

{

    header(‘Location: index.php’);

}

if(isset($_POST[‘button’]))

{

$username = $_SESSION[‘user_loggedin’]; 

$query = “SELECT * FROM customer WHERE username='”.$username.”‘ “;

$result = $mysqli->query($query) or die($mysqli->error.__LINE__);

if($result->num_rows > 0) {

while($row = $result->fetch_assoc()) {

$customername = $row[‘customername’];

$user = $row[‘username’];

$email = $row[’email’];

$city=$row[‘city’];

$description = $row[‘description’];              

}

}

 

We can fix the insecure direct object references by performing an authorization check when loading the data. In this case, the code snippet is just performing the query based on the existing session rather than the username. Now, this user profile information will be retrieved only if that user session exists. Another good part is, we are not providing any parameters controlled by the user.

Case 2: 

Now, let us go through another variant of least privilege vulnerability, which once again occurs due to missing access controls. The following code snippet is taken from a feature that is accessible only to an administrator. 

if(!isset($_SESSION[‘user_loggedin’]))

{

    header(‘Location: index.php’);

}

if(isset($_POST[‘button’]))

{

    $message = “Successfully deleted all the users”;           

}

?>

 

Clearly, the code only checks if the user has a valid session and completes the operation if a valid session is found. This means anyone with a valid session, can access this feature and they can do all the actions on behalf of an admin. The point to note here is, there is no role- based access control existing in the application to prevent unauthorized access to admin features. Users with any role can access admin features if they have a valid session on the application. It is common in applications that they serve privileged resources to unprivileged users. When a sensitive page is loaded to the user, there should be an authorization check to see if the user requesting this page has sufficient privileges to access this page or not. 

Let us go through the following code to check how this issue can be fixed.

if(!isset($_SESSION[‘admin_loggedin’]) || $_SESSION[‘role’] != ‘admin’)

{   

    header(‘Location: index.php’);

}

if(isset($_POST[‘button’]))

{  

       $message = “Successfully deleted all the users”;           

}

?>

 

In the previous case, we were just checking if the session exists. Now, we have assigned roles to each group. If the user is logged in as admin, he will be assigned to an “admin” group where he will have more privileges. So before providing access to admin pages, the user will be verified to ensure that a valid session exists and he is part of the ‘admin role’. If any of them are missing, the user will be redirected to the login page.

Conclusion

As described in this article, lack of access controls can lead to various forms of privilege escalation vulnerabilities in web applications depending on the type of functionality. A low privileged user may be able to access other users’ resources or high privileged user’s resources depending on the access controls implemented in the application. Writing secure code to prevent these vulnerabilities is extremely important as they can lead to serious damage .

 

Sources

  1. https://cheatsheetseries.owasp.org/cheatsheets/Access_Control_Cheat_Sheet.html
  2. https://portswigger.net/web-security/access-control
  3. https://owasp-aasvs.readthedocs.io/en/latest/requirement-4.1.html
Posted: November 17, 2020
Srinivas
View Profile

Srinivas is an Information Security professional with 4 years of industry experience in Web, Mobile and Infrastructure Penetration Testing. He is currently a security researcher at Infosec Institute Inc. He holds Offensive Security Certified Professional(OSCP) Certification. He blogs atwww.androidpentesting.com. Email: srini0x00@gmail.com