Test case 05 / 26FAIL
Broken Object Level Authorization - Users - User Detail API
Lab environment — not a production system
Screenshots and raw traffic are not translated; text within them may be in another language.
vuln-bank/Evidence/[FAIL] Broken Object Level Authorization - Users - User Detail API
01 — Notes
Test notes
Vulnerability
[FAIL] Broken Object Level Authorization - Users - User Detail API
Description
The /api/v3/user/<user_id> endpoint returns a user profile based on the user_id in the path without checking that the profile belongs to the token holder or that the caller is an administrator. user_id is a sequential integer.
Impact
Confidentiality (High): any authenticated user can increment user_id to harvest every customer's profile, including account number, balance, bio, and administrator flag. This data fuels follow-on attacks: harvested account numbers are used in balance IDOR and transfers, while the is_admin flag identifies high-value targets.
CWE
CWE-639: Authorization Bypass Through User-Controlled Key
OWASP
A01:2021 - Broken Access Control
Scenario
Normal: the attacker reads their own profile (user_id 2). Exploitation: user_id is changed to 3 -> the victim's profile is readable. Impact: user_id 1 is read -> the administrator profile with account number, balance, and is_admin true is exposed to an ordinary user.
Endpoint
GET http://127.0.0.1:5001/api/v3/user/<user_id>
Affected feature
User detail API (used by the admin panel for the user detail modal)
Remediation
- Restrict the endpoint to returning only the token holder's profile, and provide a separate administrative endpoint that checks the role from the database.
- Use random UUIDs as user identifiers.
- Reduce response fields to the minimum required by the interface.
Proof of concept
1) (Screenshot 1) NORMAL: the attacker reads their own profile at user_id 2.
2) (Screenshot 2) EXPLOITATION: user_id 3 is read -> the victim's profile is exposed.
3) (Screenshot 3) CIA IMPACT: user_id 1 is read -> the administrator profile, account number ADMIN001, balance, and is_admin true are exposed to an ordinary user.
View source note (English)
Vulnerability:
[FAIL] Broken Object Level Authorization - Users - User Detail API
Description:
The /api/v3/user/<user_id> endpoint returns a user profile based on the user_id in the path without checking that the profile belongs to the token holder or that the caller is an administrator. user_id is a sequential integer.
Impact:
Confidentiality (High): any authenticated user can increment user_id to harvest every customer's profile, including account number, balance, bio, and administrator flag. This data fuels follow-on attacks: harvested account numbers are used in balance IDOR and transfers, while the is_admin flag identifies high-value targets.
CWE:
CWE-639: Authorization Bypass Through User-Controlled Key
OWASP:
A01:2021 - Broken Access Control
Scenario:
Normal: the attacker reads their own profile (user_id 2). Exploitation: user_id is changed to 3 -> the victim's profile is readable. Impact: user_id 1 is read -> the administrator profile with account number, balance, and is_admin true is exposed to an ordinary user.
Endpoint:
GET http://127.0.0.1:5001/api/v3/user/<user_id>
Affected Feature:
User detail API (used by the admin panel for the user detail modal)
Remediation:
- Restrict the endpoint to returning only the token holder's profile, and provide a separate administrative endpoint that checks the role from the database.
- Use random UUIDs as user identifiers.
- Reduce response fields to the minimum required by the interface.
POC:
1) (Screenshot 1) NORMAL: the attacker reads their own profile at user_id 2.
2) (Screenshot 2) EXPLOITATION: user_id 3 is read -> the victim's profile is exposed.
3) (Screenshot 3) CIA IMPACT: user_id 1 is read -> the administrator profile, account number ADMIN001, balance, and is_admin true are exposed to an ordinary user.
02 — Screenshots
Screenshots (3)
03 — Requests and responses
HTTP captures
Some credential values are masked in this public HTML view. This does not mean every sensitive value or linked file has been redacted.
CAPTURE 01 / 1
GET /api/v3/user/2 HTTP/1.1
User-Agent: python-requests/2.33.1
Accept-Encoding: gzip, deflate, br, zstd
Accept: */*
Connection: keep-alive
Authorization: Bearer [REDACTED-LAB-TOKEN]
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 197
Access-Control-Allow-Origin: *
Server: Werkzeug/2.0.1 Python/3.9.25
Date: Wed, 30 Sep 2026 03:02:15 GMT
{
"status": "success",
"user": {
"account_number": "0932191785",
"balance": -8100.0,
"bio": null,
"id": 2,
"is_admin": false,
"username": "pentest_attacker"
}
}CAPTURE 02 / 2
GET /api/v3/user/3 HTTP/1.1
User-Agent: python-requests/2.33.1
Accept-Encoding: gzip, deflate, br, zstd
Accept: */*
Connection: keep-alive
Authorization: Bearer [REDACTED-LAB-TOKEN]
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 195
Access-Control-Allow-Origin: *
Server: Werkzeug/2.0.1 Python/3.9.25
Date: Wed, 30 Sep 2026 03:02:16 GMT
{
"status": "success",
"user": {
"account_number": "9159912486",
"balance": 10100.0,
"bio": null,
"id": 3,
"is_admin": false,
"username": "pentest_victim"
}
}CAPTURE 03 / 3
GET /api/v3/user/1 HTTP/1.1
User-Agent: python-requests/2.33.1
Accept-Encoding: gzip, deflate, br, zstd
Accept: */*
Connection: keep-alive
Authorization: Bearer [REDACTED-LAB-TOKEN]
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 185
Access-Control-Allow-Origin: *
Server: Werkzeug/2.0.1 Python/3.9.25
Date: Wed, 30 Sep 2026 03:02:17 GMT
{
"status": "success",
"user": {
"account_number": "ADMIN001",
"balance": 1000000.0,
"bio": null,
"id": 1,
"is_admin": true,
"username": "admin"
}
}