Sitemap

Broken Access Control

11 min readJul 13, 2026

--

Press enter or click to view image in full size

Broken access controls are a type of security vulnerability that arises when an application or system fails to properly restrict access to sensitive data or functionality. This vulnerability allows attackers to gain unauthorized access to resources that should be restricted, such as user accounts, files, databases, or administrative functions. Broken access controls can occur due to a variety of factors, including poor design, configuration errors, or coding mistakes. This category is critical in web applications because modern systems protect data through API endpoints, object IDs, tenant boundaries, role checks, and service-to-service requests. A logged-in user is not automatically authorized for every resource; the real security decision is whether the server verifies which action that user may perform on that specific resource.

Get Gamuchirai’s stories in your inbox

Join Medium for free to get updates from this writer.

Broken access control often appears through simple-looking but high-impact failures: viewing another user’s invoice, calling an admin endpoint as a standard user, changing user_id to access another customer's data, or manipulating a backend request to internal resources

  1. Discretionary Access Control (DAC): In this type of access control, the resource owner or administrator determines who is allowed to access a resource and what actions they are allowed to perform. DAC is commonly used in operating systems and file systems. In layman’s terms, imagine a castle where the king can give keys to his advisors, allowing them to open any doors they like, whenever they want. That’s DAC for you. It’s the liberty to control access to your own resources. The one in charge, like the king of the castle, can hand out permissions to whomever they please, dictating who can come in and out.
  2. Mandatory Access Control (MAC): In this type of access control, access to resources is determined by a set of predefined rules or policies that are enforced by the system. MAC is commonly used in highly secure environments, such as government and military systems. In layman’s terms, picture a fort with an iron-clad security protocol. Only specific individuals with particular security clearances can access certain areas, and this is non-negotiable. The high commander sets the rules, and they are rigorously followed. That’s how MAC works. It’s like the stern security officer who allows no exceptions to the rule.
  3. Role-Based Access Control (RBAC): In this type of access control, users are assigned roles that define their level of access to resources. RBAC is commonly used in enterprise systems, where users have different levels of authority based on their job responsibilities. In layman’s terms, imagine a modern corporation. You have your managers, your executives, your sales staff, etc. They each have different access to the building. Some can enter the boardroom, others can access the sales floor, and so on. That’s the essence of RBAC — assigning access based on a person’s role within an organization.
  4. Attribute-Based Access Control (ABAC): In this type of access control, access to resources is determined by a set of attributes, such as user role, time of day, location, and device. ABAC is commonly used in cloud environments and web applications. In layman’s terms, think of a highly advanced sci-fi security system that scans individuals for certain attributes. Maybe it checks whether they’re from a particular planet, whether they’re carrying a specific device, or if they’re trying to access a resource at a specific time. That’s ABAC. It’s like the smart, flexible security of the future.

Implementing access control can help prevent security breaches and unauthorized access to sensitive data. However, access control is not foolproof and can be vulnerable to various types of attacks, such as privilege escalation and broken access control vulnerabilities. Therefore, it is important to regularly review and test access control mechanisms to ensure that they are working as intended.

Broken Access Control:

Broken access control vulnerabilities refer to situations where access control mechanisms fail to enforce proper restrictions on user access to resources or data. Here are some common exploits for broken access control and examples:

  1. Horizontal privilege escalation occurs when an attacker can access resources or data belonging to other users with the same level of access. For example, a user might be able to access another user’s account by changing the user ID in the URL.
  2. Vertical privilege escalation occurs when an attacker can access resources or data belonging to users with higher access levels. For example, a regular user can access administrative functions by manipulating a hidden form field or URL parameter.
  3. Insufficient access control checks occur when access control checks are not performed correctly or consistently, allowing an attacker to bypass them. For example, an application might allow users to view sensitive data without verifying their proper permissions.
  4. Insecure direct object references occur when an attacker can access a resource or data by exploiting a weakness in the application’s access control mechanisms. For example, an application might use predictable or easily guessable identifiers for sensitive data, making it easier for an attacker to access

Assessing the Web application lab from THM

The web application for this lab, features a Dashboard, Login, and Registration form that enables users to access the dashboard of the website. From a web app pentester standpoint, the pentester will usually register an account. After the registration, the pentester will then try to check the login function for any access control vulnerabilities.

The Registration Endpoint:

Press enter or click to view image in full size

Login Endpoint

Dashboard Endpoint

Press enter or click to view image in full size

Used Burp Suite to Capture the HTTP traffic

To further analyze the requests and responses being sent and received from the server, we will use the “Proxy” module of Burp Suite to capture the HTTP traffic that is being sent to the server. The captured HTTP traffic can be used with the other modules of Burp Suite.

Press enter or click to view image in full size

These can then be manipulated or sent to other tools, such as “Repeater”, for further processing before being allowed to continue to their destination.

Press enter or click to view image in full size

Above is the captured HTTP traffic that is being sent to functions.php after login, we can observe that upon completing the login process, the web application will give us a JSON response that contains the status, message, first_name, last_name, is_admin, and redirect_link which the server uses to redirect the user to the dashboard.php with the parameter “isadmin” in the URL.

Understanding the content of the HTTP request and response:

  • The target web application does not have any implemented security headers, which indicates that there are no preventative measures (like a first line of defense) in place to protect the web application against certain types of attacks.
  • The target web application is running on a Linux operating system (Debian) and is using Apache web server (Apache/2.4.38). This information can be useful in identifying potential security vulnerabilities that may exist in the target web application.
  • The target web application utilizes PHP/8.0.19 as its backend programming language. This information is important for understanding the technology stack of the application and identifying potential security vulnerabilities or compatibility issues that may arise with other software components.
  • The target web application redirects the user to the dashboard with a parameter that we can possibly test for privilege escalation vulnerabilities

Exploiting the Web Application

We learned that the file functions.php returns a JSON response upon login. The response contains a redirect_link with a parameter that we can test for access control vulnerabilities. To start testing for this vulnerability, we can intercept the HTTP response and copy the value of the redirect_link parameter to our address bar. Since the application redirects the user to dashboard.php while the JSON response can only be seen by intercepting using a proxy tool, we can try changing the parameter’s value from “false” to “true” or vice versa.

Press enter or click to view image in full size

Upon changing the value from false to true, application redirects us to admin.php, which is hidden to a normal user by default. Below is the HTTP request that is captured using Burp Suite Proxy.

Press enter or click to view image in full size

Since we have access to admin.php using a low-privilege account, we might as well check for a vertical privilege escalation attack. Checking the box in the “Admin access” column of the account you registered and clicking the “Save Changes” button will give us admin privileges. Which in return enables us to revoke the access of other admin users

Press enter or click to view image in full size

Root Cause

Access control is the policy that determines which user can access which resource with which action. This control must be enforced in trusted server-side code, not in the client. Broken access control commonly appears when:

  • An endpoint checks login but not authorization
  • User-controlled id, account_id, users_id, or file_id values are accepted
  • Admin functions are only hidden in the UI
  • API methods use inconsistent authorization checks
  • Role data from JWTs, cookies, hidden fields, or request headers is trusted without validation
  • Multi-tenant applications do not enforce tenant isolation

Typical Attack Scenario

A user views their own order:

GET /api/orders/1001 HTTP/1.1
Host: vulnerable-app.example
Cookie: session=user_a_session

The attacker tries a different order number on the same endpoint:

GET /api/orders/1002 HTTP/1.1
Host: vulnerable-app.example
Cookie: session=user_a_session

If the application returns order 1002 without checking whether it belongs to user_a , this is an IDOR example.

Vulnerable Code

The following example fetches the record only by order_id. It does not validate the relationship between the session user and the record owner.

@app.get("/api/orders/<order_id>")
def get_order(order_id):
order = db.query("SELECT * FROM orders WHERE id = ?", [order_id])
return jsonify(order)

Defended Code

The safer approach filters by both order_id and the authenticated user's ID. Special roles such as admin should be defined through a central policy.

@app.get("/api/orders/<order_id>")
def get_order(order_id):
user = current_user()
order = db.query(
"SELECT * FROM orders WHERE id = ? AND owner_id = ?",
[order_id, user.id]
)
if not order:
abort(404)
return jsonify(order)

Mitigation based on Assessing the Web application lab from THM

There are several steps that can be taken to mitigate the risk of broken access control vulnerabilities in PHP applications:

  1. Implement Role-Based Access Control (RBAC): Role-based access control (RBAC) is a method of regulating access to computer or network resources based on the roles of individual users within an enterprise. By defining roles in an organization and assigning access rights to these roles, you can control what actions a user can perform on a system. The provided code snippet illustrates how you can define roles (such as ‘admin’, ‘editor’, or ‘user’) and the permissions associated with them. The hasPermission function checks if a user of a certain role has a specified permission.
// Define roles and permissions
$roles = [
'admin' => ['create', 'read', 'update', 'delete'],
'editor' => ['create', 'read', 'update'],
'user' => ['read'],
];

// Check user permissions
function hasPermission($userRole, $requiredPermission) {
global $roles;
return in_array($requiredPermission, $roles[$userRole]);
}

// Example usage
if (hasPermission('admin', 'delete')) {
// Allow delete operation
} else {
// Deny delete operation
}

2. Use Parameterized Queries: Parameterized queries are a way to protect PHP applications from SQL Injection attacks, where malicious users could potentially gain unauthorized access to your database. By using placeholders instead of directly including user input into the SQL query, you can significantly reduce the risk of SQL Injection attacks. The provided example demonstrates how a query can be made secure using prepared statements, which separates SQL syntax from data and handles user input safely.

// Example of vulnerable query
$username = $_POST['username'];
$password = $_POST['password'];
$query = "SELECT * FROM users WHERE username='$username' AND password='$password'";

// Example of secure query using prepared statements
$username = $_POST['username'];
$password = $_POST['password'];
$stmt = $pdo->prepare("SELECT * FROM users WHERE username=? AND password=?");
$stmt->execute([$username, $password]);
$user = $stmt->fetch();

3. Proper Session Management: Proper session management ensures that authenticated users have timely and appropriate access to resources, thereby reducing the risk of unauthorized access to sensitive information. Session management includes using secure cookies, setting session timeouts, and limiting the number of active sessions a user can have. The code snippet shows how to initialize a session, set session variables and check for session validity by looking at the last activity time.

// Start session
session_start();

// Set session variables
$_SESSION['user_id'] = $user_id;
$_SESSION['last_activity'] = time();

// Check if session is still valid
if (isset($_SESSION['last_activity']) && (time() - $_SESSION['last_activity'] > 1800)) {
// Session has expired
session_unset();
session_destroy();
}

4. Use Secure Coding Practices: Secure coding practices involve methods to prevent the introduction of security vulnerabilities. Developers should sanitize and validate user input to prevent malicious data from causing harm and avoid using insecure functions or libraries. The given example shows how to sanitize user input using PHP’s filter_input function and demonstrates how to securely hash a password using password_hash instead of an insecure function like md5.

// Validate user input
$username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING);
$password = filter_input(INPUT_POST, 'password', FILTER_SANITIZE_STRING);

// Avoid insecure functions
// Example of vulnerable code using md5
$password = md5($password);
// Example of secure code using password_hash
$password = password_hash($password, PASSWORD_DEFAULT);

Testing Approach

Access control testing requires more than one user. At minimum, use accounts with different privilege levels:

  • Anonymous user
  • Standard user
  • Different standard user
  • Privileged user
  • Admin or tenant owner

Compare the same endpoints with each role’s session. Test GET, POST, PUT,PATCH, and DELETE separately. An application may enforce authorization for GET but forget it for DELETE

Defensive Controls

  • Use deny-by-default.
  • Enforce authorization through central middleware or policy.
  • Make resource ownership checks mandatory in the domain model.
  • Apply tenant isolation in database queries and service logic.
  • Do not trust client-side role, price, limit, or owner data.
  • Restrict CORS to trusted origins.
  • Log access control failures and alert on repeated attempts.

The impact of these types of privilege escalation can vary depending on the specific system and the level of access that is gained. However, in general, the consequences can include unauthorized access to sensitive information, data loss or theft, disruption of critical systems or services, and even complete network compromise. Therefore, it is important to implement strong access controls and regularly monitor for any signs of unauthorized access or activity.

Reporting Note

A good access control report does not only say “another user’s data is visible.” It shows which role accessed which resource, the expected behavior, the actual response, the affected data type, and the recommended server-side ownership control.

--

--

Gamuchirai
Gamuchirai

SOC Analyst| Cyber Threat Intel | DFIR | A Curious Geek | Content Writer | Blessed.Planting seeds that will be fruitful and also impactful. | Ordained by God