Lab 01: OWASP A01 — Broken Access Control

Objective

Exploit real Broken Access Control vulnerabilities on a live vulnerable server using Kali Linux tools: enumerate hidden endpoints with gobuster, exploit IDOR to steal PII and credit cards from other users, access unauthenticated admin panels, perform path traversal to read system files, and escalate privileges via mass assignment — then observe the secured version that blocks every attack.

Background

Broken Access Control is the #1 OWASP vulnerability (2021), found in 94% of applications tested. It covers any situation where users can act outside their intended permissions: reading other users' data (IDOR), accessing admin pages without credentials, traversing file paths, or escalating their own privileges. Unlike SQL injection, these bugs require no special encoding — just changing an ID number in a URL.

Architecture

┌─────────────────────┐         Docker Network: lab-a01          ┌─────────────────────┐
│   KALI ATTACKER     │ ──────────── HTTP attacks ─────────────▶ │   VICTIM SERVER     │
│  innozverse-kali    │                                           │  innozverse-cybersec│
│  (your terminal)    │ ◀─────────── responses ──────────────── │  Flask API :5000    │
└─────────────────────┘                                           └─────────────────────┘

Time

45 minutes

Prerequisites

  • Docker installed and running

  • Basic curl knowledge

Tools

  • Victim: zchencow/innozverse-cybersec:latest (Flask vulnerable app)

  • Attacker: zchencow/innozverse-kali:latest (Kali Linux with pentest tools)


Lab Instructions

Step 1: Environment Setup — Launch Victim Server

Open a terminal and run these commands to create the lab network and start the vulnerable target:

📸 Verified Output:

💡 The victim server is victim-a01 on the lab-a01 Docker network. Docker's internal DNS resolves victim-a01 to the container's IP automatically. The Kali attacker container will reference the target by hostname — exactly like attacking a machine on your LAN.


Step 2: Launch Kali Attacker — Recon Phase

You are now inside Kali Linux on the same network as the victim. All subsequent commands run inside this Kali container:

📸 Verified Output:


Step 3: Service Fingerprinting — nmap + whatweb

📸 Verified Output:

💡 Fingerprinting tells us the server is Python/Flask (Werkzeug). This matters: Flask apps commonly have IDOR bugs (no ORM-level access control), debug mode exposure, and predictable error formats. A real attacker uses this to select the right payloads.


Step 4: Directory Enumeration — gobuster

📸 Verified Output:

📸 Verified Output:


Step 5: IDOR Attack — Steal All Users' PII

Scenario: You are logged in as bob (user ID 3). The API endpoint /api/users/<id> returns any user record — no ownership check.

📸 Verified Output:

📸 Verified Output:

💡 IDOR (Insecure Direct Object Reference) is the #1 API vulnerability. The attacker simply increments the ID number. In real applications, this exposes millions of records. The fix is a single server-side check: if order.user_id != current_user.id: return 403. No framework does this automatically — every developer must add it explicitly.


Step 6: IDOR on Orders — Financial Data Exposure

📸 Verified Output:


Step 7: Unauthenticated Admin Panel — Zero Auth Required

📸 Verified Output:


Step 8: Path Traversal — Read System Files

📸 Verified Output:


Step 9: Mass Assignment — Privilege Escalation

📸 Verified Output:

💡 Mass assignment is when the server blindly applies all client-supplied fields. The fix is an explicit allowlist: only permit {username, email, password} to be updated via this endpoint. The role field must only be settable by an admin via a separate privileged endpoint.


Step 10: Cleanup

Back on your host:


Remediation — What the Fix Looks Like

Vulnerability
Vulnerable Code
Fix

IDOR (users)

SELECT * FROM users WHERE id=? no owner check

WHERE id=? AND id=current_user_id

IDOR (orders)

Returns any order by ID

WHERE id=? AND user_id=current_user_id

No auth on admin

No decorator

@require_role('admin') on every admin route

Path traversal

path = request.args.get('path') used directly

Allowlist of safe paths; os.path.abspath + prefix check

Mass assignment

Update any field from request body

Explicit allowlist: only {username, email, password}

Data export

No auth

Auth + role check + rate limit

Summary

Attack
Tool
Finding

Recon

nmap, whatweb

Python/Flask, Werkzeug 3.1.6

Dir enum

gobuster

Found /admin/panel, /admin/users, /api/export

IDOR (users)

curl

Stole SSN + credit card for all 4 users

IDOR (orders)

curl

Accessed all 5 orders including admin's

No-auth admin

curl

Leaked JWT secret + DB password

Path traversal

curl

Read /etc/passwd, /etc/shadow, SSH keys

Mass assignment

curl

Escalated bob from useradmin

Further Reading

Last updated