Skip to content

Broken access control

OWASP

OWASP Web Security Testing Guide 4.2 > 5. Authorization Testing > 5.2. Testing for Bypassing Authorization Schema

ID Link to Hackinglife Link to OWASP Description
5.2 WSTG-ATHZ-02 Testing for Bypassing Authorization Schema - Assess if horizontal or vertical access is possible. - Access to Administrative functions by force browsing (/admin/addUser)

Access control determines whether the user is allowed to carry out the action that they are attempting to perform. In the context of web applications, access control is dependent on authentication and session management.

  • Authentication confirms that the user is who they say they are.
  • Session management identifies which subsequent HTTP requests are being made by that same user.

Types of broken access control:

  • Vertical access control: a regular user can access or perform operations on endpoints reserved to admins.
  • Horizontal access control: a regular user can access resources or perform operations on other users.
  • Context-dependent access control: Context-dependent access controls restrict access to functionality and resources based upon the state of the application or the user's interaction with it. For example, a retail website might prevent users from modifying the contents of their shopping cart after they have made payment.

Exploitation

This is how you usually test these vulnerabilities:

Unprotected functionality

At its most basic, vertical privilege escalation arises where an application does not enforce any protection for sensitive functionality. Example: accessing /admin panel (or a less obvious url for the admin functionality.)

Parameter-based access control methods

When the application makes access control decisions based on a submitted value.

https://insecure-website.com/login/home.jsp?admin=true

This approach is insecure because a user can modify the value and access functionality they're not authorized to, such as administrative functions. In the following example, I'm the user wiener, but I can access to user carlos information by modifying the parameter id in the request:

GET /my-account?id=carlos HTTP/2

For GUID and obfuscated parameters, you can chain a data exposure vulnerability with this. Also, an IDOR.

URL override methods

There are various non-standard HTTP headers that can be used to override the URL in the original request, such as X-Original-URL and X-Rewrite-URL.

If a website uses rigorous front-end controls to restrict access based on the URL, but the application allows the URL to be overridden via a request header, then:

1
2
3
4
POST / HTTP/1.1
Host: target.com
X-Original-URL: /admin/deleteUser 
...

URL-matching discrepancies

Websites can vary in how strictly they match the path of an incoming request to a defined endpoint.

  • For example, they may tolerate inconsistent capitalization, so a request to /ADMIN/DELETEUSER may still be mapped to the /admin/deleteUser endpoint. If the access control mechanism is less tolerant, it may treat these as two different endpoints and fail to enforce the correct restrictions as a result.
  • Spring framework with useSuffixPatternMatch option enabled allows paths with an arbitrary file extension to be mapped to an equivalent endpoint with no file extension.
  • On other systems, you may encounter discrepancies in whether /admin/deleteUser and /admin/deleteUser/

IDORS

Insecure Direct Object References (IDOR) occurs if an application uses user-supplied input to access objects directly and an attacker can modify the input to obtain unauthorized access.

Just exposing a direct reference to an internal object or resource is not a vulnerability in itself. However, this may make it possible to exploit another vulnerability: a weak access control system.  The main takeaway is that an IDOR vulnerability mainly exists due to the lack of an access control on the back-end.

The most basic example of an IDOR vulnerability is accessing private files and resources of other users that should not be accessible to us, like personal files or credit card data, which is known as IDOR Information Disclosure Vulnerabilities. Depending on the nature of the exposed direct reference, the vulnerability may even allow the modification or deletion of other users' data, which may lead to a complete account takeover.

Identifying Direct Object References

1. Study the HTTP requests to look for URL parameters or APIs with an object reference (e.g. ?uid=1 or ?filename=file_1.pdf).

2. Identify unused parameters or APIs in the front-end code in the form of JavaScript AJAX calls.

For example, if we did not have an admin account, only the user-level functions would be used, while the admin functions would be disabled. The following example shows a basic example of an AJAX call not removed from the frontend:

function changeUserPassword() {
    $.ajax({
        url:"change_password.php",
        type: "post",
        dataType: "json",
        data: {uid: user.uid, password: user.password, is_admin: is_admin},
        success:function(result){
            //
        }
    });
}

The above function may never be called when we use the web application as a non-admin user.

Using weak Hashing/Encoding methods

Base64 encoding

For example, if we see a reference like (?filename=ZmlsZV8xMjMucGRm), we can immediately guess that the file name is base64 encoded (from its character set), which we can decode to get the original object reference of (file_123.pdf).  Then, we can try encoding a different object reference (e.g. file_124.pdf) and try accessing it with the encoded object reference (?filename=ZmlsZV8xMjQucGRm), which may reveal an IDOR vulnerability if we were able to retrieve any data.

Unsafe coding:

The object reference may be hashed, like (download.php?filename=c81e728d9d4c2f636f067f89cc14862c). At a first glance, we may think that this is a secure object reference, as it is not using any clear text or easy encoding. However, if we look at the source code, we may see what is being hashed before the API call is made:

Code: javascript

1
2
3
4
5
6
7
8
9
$.ajax({
    url:"download.php",
    type: "post",
    dataType: "json",
    data: {filename: CryptoJS.MD5('file_1.pdf').toString()},
    success:function(result){
        //
    }
});

In this case, we can see that code uses the filename and hashing it with CryptoJS.MD5, making it easy for us to calculate the filename for other potential files.

Additionally we can use tools such as hash-identifier:

1
2
3
4
5
hash-identifier c81e728d9d4c2f636f067f89cc14862c 

#### Results:
Possible Hashs:
[+] MD5

Identifying Insecure APIs

Sometimes we can abuse some endpoints of an API using object references.

Prevention

1. We should always use strong and unique references, like salted hashes or UUID's. For example, we can use UUID V4 to generate a strongly randomized id for any element, which looks something like (89c9b29b-d19f-4515-b2dd-abb6e693eb20). Then, we can map this UUID to the object it is referencing in the back-end database, and whenever this UUID is called, the back-end database would know which object to return.

2. We should never calculate hashes on the front-end. We should generate them when an object is created and store them in the back-end database. Then, we should create database maps to enable quick cross-referencing of objects and references.

Abusing Referer Request header

The Referer header can be added to requests by browsers to indicate which page initiated a request.

For example, an application robustly enforces access control over the main administrative page at /admin, but for sub-pages such as /admin/deleteUser only inspects the Referer header. If the Referer header contains the main /admin URL, then the request is allowed.

Other Headers to Consider for location-base control

Often admin panels or administrative related bits of functionality are only accessible to clients on local networks, therefore it may be possible to abuse various proxy or forwarding related HTTP headers to gain access. Some headers and values to test with are:

  • Headers:
    • X-Forwarded-For
    • X-Forward-For
    • X-Remote-IP
    • X-Originating-IP
    • X-Remote-Addr
    • X-Client-IP
  • Values
    • 127.0.0.1 (or anything in the 127.0.0.0/8 or ::1/128 address spaces)
    • localhost
    • Any RFC1918 address:
      • 10.0.0.0/8
      • 172.16.0.0/12
      • 192.168.0.0/16
    • Link local addresses: 169.254.0.0/16
Last update: 2025-01-13
Created: April 30, 2024 20:40:09