«
‹
HACKAACADEMY
OP-05 // OPERATION OPEN FILES // IDOR
0
XP
R1
RANK
0%
DETECT
↻
RESET
In Operation Silent Hand, Shadow exploited CSRF to silently forge a funds transfer inside an official's own browser. The official never touched the keyboard. USD 50,000 moved. The request looked legitimate — it was anything but.
CAMPAIGN 3 — OPERATION OPEN FILES
IDOR // TARGET: NEXUS DOCUMENT VAULT
05
OWASP TOP 10 #1 — A01:2021
INSECURE DIRECT OBJECT REFERENCE
HORIZONTAL ESCALATION // PARAMETER TAMPERING // MASS DATA THEFT
OPERATION OPEN FILES
📡
SITUATION REPORT
CLASSIFIEDThe Syndicate stages its stolen intel in a document vault hosted in a Tallinn data-haven — the dead-drop where cells exchange surveillance dossiers, financial records and forged identity documents before they go to buyers.
Every file has a URL like
He never added an ownership check. The server fetches whatever ID you ask for — yours, mine, anyone's. Change the number. Get a different file. It really is that simple.
Every file has a URL like
/files/view?id=1042. You log in as yourself and see your files. But SCRIBE, the vault's developer, made one fatal assumption: that operatives would only ever type in their own file IDs.He never added an ownership check. The server fetches whatever ID you ask for — yours, mine, anyone's. Change the number. Get a different file. It really is that simple.
THE NUMBERED LOCKER WITH NO LOCK
10-YEAR-OLD LEVEL
Imagine a building where every room has a number. To access a room, you simply tell the receptionist the number.
But there is a hidden problem. The receptionist never checks whether you are allowed to access that specific room. He only checks whether the number exists.
Now imagine someone starts trying different room numbers. They discover they can access rooms belonging to other people just by knowing the correct number. Because the system assumes knowing the identifier is the same as being allowed, but ownership is never verified.
But there is a hidden problem. The receptionist never checks whether you are allowed to access that specific room. He only checks whether the number exists.
Now imagine someone starts trying different room numbers. They discover they can access rooms belonging to other people just by knowing the correct number. Because the system assumes knowing the identifier is the same as being allowed, but ownership is never verified.
If the server fetches any file by ID without checking who owns it — what is the only thing stopping you from reading every file in the vault?
INTERCEPTED — SCRIBE COMMS
09:05 UTC
SCRIBE
"Every file sits behind a login. No account, no vault. And an operative only ever sees their own IDs — nobody stumbles onto a dossier that isn't theirs."
MENDAX
Shadow — he's leaning on secrecy and calling it security. The login proves we're inside the Tallinn vault; it never proves a file is ours. And secrecy dies the instant you add one to a number. We're already authenticated. Now we count.
▶ MISSION OBJECTIVES
01
TARGET: The NEXUS file vault at vault.nexus — a /files/view?id= endpoint that checks you are logged in but never checks the file is yours
02
EXPLOIT: Tamper the ID parameter — increment past your own file 1042 to pull other users' intelligence reports straight out of the vault
03
SWEEP: Classify NEXUS URL parameters — flag which ones are IDOR-vulnerable object references and which are safely controlled
04
WIN: Capture the exposed reports, then lock it down — the server-side ownership check that ties every object to its owner
⚖️
ETHICAL NOTICE: IDOR is covered by CEH, OSCP, and every cybersecurity certification. All interactions here are simulated against fictional infrastructure. Never use these techniques on real systems without explicit written authorisation.
🔧 UNDER THE HOOD▼
THE ATTACK — STEP BY STEP
IDOR (Insecure Direct Object Reference) — change a user-controlled ID to access someone else's data. Classic numeric enumeration:
// Your account URL:
GET /api/profile?user_id=1042
// Change to access another user:
GET /api/profile?user_id=1041
GET /api/profile?user_id=1040
// Script to enumerate all profiles:
for i in $(seq 1000 1100); do
curl -s -H "Cookie: session=YOUR_TOKEN" \
"https://victim.com/api/profile?user_id=$i"
done
IDOR in request body — the server trusts the client-supplied ID even in POST requests:POST /api/update-email
{"user_id": 9999, "email": "attacker@evil.com"}
COMMON VARIATIONS
1. GUID/UUID IDOR — UUIDs look unguessable but may be leaked in other API responses, logs, or referrer headers. Collect them and try them directly.
2. Indirect IDOR via file path — the object reference is a filename:
2. Indirect IDOR via file path — the object reference is a filename:
GET /api/download?file=invoice_1042.pdf
// Try:
GET /api/download?file=invoice_1041.pdf
3. IDOR in second-level objects — your ID is correct but a nested resource belongs to someone else:GET /api/orders/MY_ORDER/items/9999
// item 9999 belongs to a different user
HOW TO DEFEND
Enforce object-level authorization on every single endpoint — never rely on IDs in the request being trusted:
// Node.js Express middleware pattern
async function getProfile(req, res) {
const requestedId = req.params.userId;
const currentUserId = req.session.userId; // from auth token, not request body
// ALWAYS check ownership before returning data
const profile = await db.query(
'SELECT * FROM profiles WHERE id = $1 AND owner_id = $2',
[requestedId, currentUserId]
);
if (!profile) return res.status(403).json({ error: 'Forbidden' });
return res.json(profile);
}
Use indirect references: map user-visible IDs to internal IDs server-side. Never expose sequential database primary keys directly.TARGET
nexus-docs.ghost-capital.int
IP ADDRESS
10.47.0.55
OS / WEB SERVER
Ubuntu 22.04 · nginx/1.18.0
KEY SERVICES
PHP/7.4.28 · MySQL 8.0
ATTACK SCOPE
/files/view?id=* — all document IDs in scope
ATTACKER NODE
shadow@sigma9 · 10.99.0.1
📋 ROOM TASKS
01
✓
Understand what ownership check is missing
02
▶
Enumerate documents belonging to other users
03
○
Classify IDOR-risky vs safe URL parameters
04
○
Identify the server-side ownership-check fix
05
○
Submit the capture-the-flag token
CAPTURE THE FLAG
Complete the exploit lab. The flag appears in the terminal output. Copy and submit it here for +50 XP.
PHASE 01
TAMPER THE ID
EXPLOIT
MENDAX
ENCRYPTED
You changed one number in the URL —
The server checked your session cookie — confirmed you are logged in — then fetched the file and showed it to you. That is the entire check. It never asks: is this file yours?
You are logged in with your own valid account, your own file at ID 1042 — yet the vault just handed you someone else's.
You just opened a file that isn't yours. Now make the call: why did one number unlock it?
id=1042 to id=1043 — and another user's file opened in front of you. Same login, different person's data:https://vault.nexus/files/view?id=1042The server checked your session cookie — confirmed you are logged in — then fetched the file and showed it to you. That is the entire check. It never asks: is this file yours?
You are logged in with your own valid account, your own file at ID 1042 — yet the vault just handed you someone else's.
You just opened a file that isn't yours. Now make the call: why did one number unlock it?
MENDAX — HOW THIS IS ACTUALLY DONE
LIVE
MENDAX
Here's the real method — and it's almost embarrassingly simple. On a fictional target like this one, in scope and authorised, an analyst just logs in with their own account and replays the file request, changing only the ID. I script it with curl using my own session cookie:
$ for id in 1041 1042 1043 1044; do
curl -s -b "session=$MY_COOKIE" \
"https://vault.nexus/files/view?id=$id" -o file_$id.txt
done
# file_1041.txt belongs to someone else — and it opened
MENDAX
No password cracking. No exploit. The server trusted the ID because we were logged in — it never checked the file was ours. That gap has a name, and the fix is one ownership check. First, you name the flaw.
▶ PICK THE CORRECT EXPLANATION
💡 MENDAX — HINT (−20 XP)
The server does two jobs when you request a file: check your session, then fetch the file. Which of those two jobs is it skipping? Which answer describes a missing step — not a bypass of the first step?
✓
IDOR MECHANISM UNDERSTOOD
Authentication and authorisation are two completely different things. Authentication asks: who are you? Authorisation asks: what are you allowed to do? IDOR happens when a server does authentication but skips authorisation for specific objects.
In simple terms: Getting into the gym proves you are a member. It does not prove locker 48 is yours. The server let us into the vault — but it never checks which drawers we are allowed to open. So we open all of them.
SCRIBE built a door at the entrance. He forgot to put locks on anything inside.
In simple terms: Getting into the gym proves you are a member. It does not prove locker 48 is yours. The server let us into the vault — but it never checks which drawers we are allowed to open. So we open all of them.
SCRIBE built a door at the entrance. He forgot to put locks on anything inside.
Real-world impact: In 2021, Parler exposed 70 million user records via IDOR — public posts had sequential IDs, no ownership check, no rate limiting. One researcher wrote a script and downloaded the entire dataset before the platform went offline.
PHASE 02
ENUMERATE THE VAULT — CHANGE THE NUMBER, GET THE FILE
TERMINAL
IDOR confirmed. Being logged in means nothing if the server never checks ownership. Walk the ID sequence — each number is a different agent's classified file, and every door is open.
MENDAX
ENCRYPTED
We are logged into the vault as
Think of the numbered gym lockers. Your membership gets you through the front door. But nobody ever checked which locker is yours. Try the one next to yours. And the next. And the next.
The browser bar below is live. Tap the ID number, change it, press Go — see whose file loads. Work through the IDs. Find the intelligence reports.
op_shadow. Our file is at ID 1042.Think of the numbered gym lockers. Your membership gets you through the front door. But nobody ever checked which locker is yours. Try the one next to yours. And the next. And the next.
The browser bar below is live. Tap the ID number, change it, press Go — see whose file loads. Work through the IDs. Find the intelligence reports.
▶ CHANGE THE ID NUMBER — PRESS GO — SEE WHOSE FILE LOADS
Your file is ID 1042. Try other numbers. Any file that loads and isn't yours proves IDOR.
MISSION TARGETS — FIND THESE 3 FILES
☐ NEXUS network map (try IDs around 1012)
☐ Operative identity documents (try IDs around 1038)
☐ Shell company accounts (try IDs around 1055)
LEAVE MISSION?
Progress is saved. You can resume from the mission select screen at any time.
RESET MISSION?
This wipes all progress for this operation only. XP in other operations is unaffected.
ARE YOU SURE?
Final confirmation -- all progress for this operation will be permanently erased.
💡 MENDAX — ACTIVE HINT
Change the number in the URL bar and press Go. Try 1043 first — it will load someone else's file and prove IDOR. Then try numbers near 1012, 1038, and 1055 to find the three target files.
✓
VAULT EMPTIED — 58 FILES ACCESSED, NONE OURS
One authenticated account. One loop through 61 sequential IDs. 58 files belonging to other users — downloaded, read, extracted. Zero hacking. Zero exploits. Just counting.
Simple version: We walked into the gym, tried every numbered locker, and took whatever was inside the unlocked ones. We never broke a lock. We never picked a pocket. The lockers were just open.
Why this scales dangerously: A script can enumerate thousands of IDs per minute. A vulnerable app with 1 million records can be completely exfiltrated in hours. The attacker only needs one valid account — then they can access everything.
Simple version: We walked into the gym, tried every numbered locker, and took whatever was inside the unlocked ones. We never broke a lock. We never picked a pocket. The lockers were just open.
Why this scales dangerously: A script can enumerate thousands of IDs per minute. A vulnerable app with 1 million records can be completely exfiltrated in hours. The attacker only needs one valid account — then they can access everything.
Real impact: The 2021 Parler breach used IDOR on sequential post IDs. A researcher enumerated the entire platform — 70 million records — before it went offline. No exploit. No vulnerability scanner. Just a for loop.
PHASE 03
CLASSIFY THE PARAMETERS — IDOR OR SAFE?
TAP & SORT
Vault raided. Now map the full attack surface. IDOR only bites when a parameter points at a specific user-owned object — learn to tell the dangerous IDs from the harmless ones on sight.
MENDAX
ENCRYPTED
SCRIBE is reviewing URL parameters across NEXUS platforms — trying to identify which ones are IDOR vulnerabilities and which are genuinely safe.
MENDAX: "Shadow — classify each parameter. Tap it, then mark it IDOR RISK if changing the value could expose another user's data, or SAFE if it cannot.">
The test: does this parameter fetch a specific object that belongs to a user — a file, invoice, message, profile? If yes and no ownership check exists — IDOR risk. If it's a search term, display preference, or page number — safe.
Get them all right to proceed.
MENDAX: "Shadow — classify each parameter. Tap it, then mark it IDOR RISK if changing the value could expose another user's data, or SAFE if it cannot.">
The test: does this parameter fetch a specific object that belongs to a user — a file, invoice, message, profile? If yes and no ownership check exists — IDOR risk. If it's a search term, display preference, or page number — safe.
Get them all right to proceed.
▶ TAP AN INPUT — THEN TAP A BUCKET
Tap an input chip to select it, then tap IDOR RISK or SAFE to classify it.
⚠ IDOR RISK
✓ SAFE
✓
ALL PARAMETERS CLASSIFIED — IDOR SURFACE MAPPED
Perfect classification. You can now spot IDOR-vulnerable parameters on sight.
Simple rule: Any parameter that contains an ID pointing to a user-owned object is a potential IDOR —
The test: if I change this value, does it fetch something that belongs to a different person?
Simple rule: Any parameter that contains an ID pointing to a user-owned object is a potential IDOR —
id=, user_id=, invoice_id=, msg_id=. Search terms, display preferences, page numbers — these do not fetch owned objects, so they cannot expose other users' data.The test: if I change this value, does it fetch something that belongs to a different person?
Why user_id= in a URL is almost always IDOR: Developers who pass user_id as a parameter are trusting the client to provide their own ID. Attackers change it to someone else's. The fix: derive user identity from the session on the server — never trust a user-supplied ID.
PHASE 04
THE FIX — CLOSE THE DOOR
DEFENSE
58 files accessed. The system never asked whose they were. Authentication proved you entered the building — but authorisation is the check the system skipped. Name the one SQL addition that closes every door in the vault.
MENDAX — DEBRIEF
FINAL PHASE
GHOST is being brought in. The documents are secured.
MENDAX: "Shadow — debrief question. NEXUS's development team is patching the portal right now. Which single fix would have stopped the entire attack? The attacker knew the URL structure. They could guess any ID. The gap was not authentication — the user was logged in. It was authorisation — the server never asked 'does this user own this object?'"
MENDAX: "Shadow — debrief question. NEXUS's development team is patching the portal right now. Which single fix would have stopped the entire attack? The attacker knew the URL structure. They could guess any ID. The gap was not authentication — the user was logged in. It was authorisation — the server never asked 'does this user own this object?'"
▶ WHICH FIX STOPS IDOR?
💡 MENDAX — HINT (−20 XP)
Think about WHY the attack worked: the server fetched any file we asked for, as long as we were logged in. It never asked: does this user own this file? The fix adds that missing question. Where should that check happen — and what should the server compare?
► INTEL — OP-05 // OPERATION OPEN FILES
TARGET: NEXUS Document Repository
Classification: TOP SECRET // Campaign 3 Ghost Protocol
MENDAX — CHANNEL BRIEFING
PRE-OP
MENDAX
The document download endpoint is /download?id=N where N is a sequential integer. No session ownership check. ID 1-100 are executive documents.
📓
OWASP CLASSIFICATION
INTELA01:2021 — IDOR is the most common access control failure. The server trusts user-supplied object references without verifying the requester's relationship to that object.
⚖
GLOSSARY TERMS: IDOR, Insecure Direct Object Reference, Horizontal Privilege Escalation, Parameter Tampering. All terms auto-logged to your Field Manual as you encounter them.
▶ ACADEMY — INSECURE DIRECT OBJECT REFERENCE
AUTHENTICATION OPENS THE DOOR.
IDOR MEANS THERE ARE NO LOCKS INSIDE.
IDOR MEANS THERE ARE NO LOCKS INSIDE.
Three levels of depth — start at Beginner, go as deep as you want.
BEGINNER
What Is IDOR?
›
IDOR — Insecure Direct Object Reference — happens when an application uses a user-controlled value (like a number in a URL) to fetch an object, without checking whether that user is allowed to access it.
Here is how it feels from your side as an attacker: you log in, you see your profile at
The two things that make IDOR possible:
• The server uses a user-supplied value to directly reference an internal object
• The server checks authentication (are you logged in?) but skips authorisation (do you own this object?)
Here is how it feels from your side as an attacker: you log in, you see your profile at
/profile?id=1042. You change 1042 to 1043. Someone else's profile loads. You change it to 1 — you get the administrator's profile.The two things that make IDOR possible:
• The server uses a user-supplied value to directly reference an internal object
• The server checks authentication (are you logged in?) but skips authorisation (do you own this object?)
Real world: In 2021, Parler — a social media platform — exposed all 70 million public posts via IDOR. Sequential post IDs, no ownership check, no rate limiting. One researcher downloaded the entire platform before it went offline.
INTERMEDIATE
How IDOR Attacks Are Executed
›
Manual IDOR test:
1. Log in, find a URL with an ID:
2. Change the ID:
3. If a different invoice loads — IDOR confirmed
Automated enumeration:
1000 requests, 1000 different objects — all returned to the attacker.
IDOR is not just GET requests:
• POST body:
• JSON API:
• File upload path:
Horizontal vs vertical IDOR:
• Horizontal — same privilege level, different user: read peer's files
• Vertical — lower privilege accesses higher privilege data: viewer reads admin files
1. Log in, find a URL with an ID:
/invoice?id=88212. Change the ID:
/invoice?id=88203. If a different invoice loads — IDOR confirmed
Automated enumeration:
for i in $(seq 1000 2000); do curl -s "site.com/file?id=$i" -b session=token; done1000 requests, 1000 different objects — all returned to the attacker.
IDOR is not just GET requests:
• POST body:
{"delete_id": 9921} — delete someone else's account• JSON API:
PUT /api/orders/441 {status: cancelled} — cancel someone's order• File upload path:
/uploads/user_99/photo.jpg — access by guessing pathHorizontal vs vertical IDOR:
• Horizontal — same privilege level, different user: read peer's files
• Vertical — lower privilege accesses higher privilege data: viewer reads admin files
EXPERT
Advanced IDOR, Bypasses & CVEs
›
Chained IDOR: Find a user ID via IDOR → use that ID to access their messages → find their email → reset their password. One IDOR can cascade into full account takeover.
IDOR in APIs: REST APIs are especially vulnerable.
Mass Assignment IDOR: POST body includes a role field:
Notable CVEs:
• CVE-2023-3932 — GitLab IDOR allowing access to private project data
• CVE-2021-22205 — GitLab IDOR + file upload = RCE (10.0 CVSS)
• CVE-2020-28949 — IDOR in Moodle LMS exposing all user assignments
IDOR in APIs: REST APIs are especially vulnerable.
GET /api/v1/users/99/data — change 99 to any user ID. GraphQL: modify the id argument in a query. Mobile apps: intercept with Burp, find IDs in JSON responses.Mass Assignment IDOR: POST body includes a role field:
{"name":"shadow","role":"admin"}. If the server blindly maps all fields — attacker promotes themselves to admin. Same root cause: trusting user-supplied values for privileged objects.Notable CVEs:
• CVE-2023-3932 — GitLab IDOR allowing access to private project data
• CVE-2021-22205 — GitLab IDOR + file upload = RCE (10.0 CVSS)
• CVE-2020-28949 — IDOR in Moodle LMS exposing all user assignments
Facebook 2018 (HackerOne): An IDOR in the ads platform allowed any advertiser to access any other advertiser's creative assets — images, videos, copy — by changing an asset ID. Patched after responsible disclosure. Bounty paid: $5,000.
▶ REAL-WORLD TOOLS — IDOR
WHAT PROFESSIONALS USE
Every tool here is free, legal, and used in real penetration tests.
🔎
Burp Suite — Intruder
FREE TIER
Use Burp Intruder to automate IDOR enumeration. Send a request to Intruder, mark the ID parameter as a payload position, set a number range, and fire. Burp tries every ID and flags non-standard responses.
Send to Intruder → Add § around id value → Payloads: Numbers → Start attack
🔁
Autorize (Burp Extension)
FREE
Burp extension that automatically retests every request with a lower-privileged session. Browse as admin, Autorize retests each request as a regular user. Flags any response that returns the same data — that is IDOR.
Burp → Extensions → Autorize → Set low-priv cookie → Browse normally
🐍
ffuf
FREE / OPEN SOURCE
Fast web fuzzer. Feed it a range of IDs and it enumerates endpoints faster than Burp Intruder's free tier. Filters by response size to identify valid vs invalid object responses automatically.
ffuf -u "https://site.com/file?id=FUZZ" -w ids.txt -fs 512
🛡️
OWASP ZAP — Access Control Scanner
FREE / OPEN SOURCE
ZAP's Access Control add-on tests whether authenticated users can access resources belonging to other users. Requires two sessions — one per user — then systematically cross-tests access.
Tools → Access Control Testing → Configure users → Run scan