But here's the problem:

Most real-world API vulnerabilities don't come from complex exploits — they come from simple design mistakes.

To understand this deeply, I built a deliberately vulnerable API, exploited it, and then hardened it step by step.

This hands-on approach helped me move beyond theory and actually understand how API security breaks in practice.

None
Typical SSRF Attack Flow

🧱 Project Overview

In this lab, I built a simple Flask-based API with three endpoints:

/fetch        → Fetch external URLs (SSRF)
/user/<id>    → Fetch user data (IDOR)
/admin        → Admin access control

Each endpoint was intentionally designed to demonstrate a real-world vulnerability.

⚠️ Phase 1 — Building a Vulnerable API

Let's break down what was wrong.

🔴 1. SSRF (Server-Side Request Forgery)

Vulnerable Code

@app.route("/fetch")
def fetch():
    url = request.args.get("url")
    response = requests.get(url)
    return response.text

❌ What's the problem?

The server blindly trusts user input and makes a request to any URL.

💥 Exploitation

http://127.0.0.1:5000/fetch?url=http://127.0.0.1:5000/user/1

👉 The server makes a request to itself (internal service)

🧠 Why this is dangerous

In real-world cloud environments, this can expose:

  • IAM credentials
  • Metadata services (169.254.169.254)
  • Internal APIs
  • Private network services

SSRF turns your server into an attack proxy.

🔴 2. IDOR (Insecure Direct Object Reference)

Vulnerable Code

@app.route("/user/<id>")
def get_user(id):
    return users.get(id, "User not found")

❌ What's the problem?

There is no access control.

💥 Exploitation

/user/1  → Alice
/user/2  → Bob

👉 Any user can access any other user's data.

🧠 Why this is dangerous

This leads to:

  • Data leakage
  • Privacy violations
  • Account takeover scenarios

🔴 3. Broken Admin Authorization

Vulnerable Code

@app.route("/admin")
def admin():
    role = request.headers.get("Role")

    if role == "admin":
        return "Welcome admin"

❌ What's the problem?

The server trusts a client-controlled header.

💥 Exploitation

curl -H "Role: admin" http://127.0.0.1:5000/admin

👉 Instant admin access.

🧠 Lesson

Never trust anything coming from the client.

🛠️ Phase 2 — Hardening the API

Now comes the most important part: fixing the system.

🛡️ Fix 1 — SSRF Protection

Approach

  • Parse the URL
  • Extract hostname
  • Resolve IP
  • Block internal/private IP ranges

Hardened Logic (Concept)

User input URL
        ↓
Parse hostname
        ↓
Resolve IP
        ↓
If private → Block
Else → Allow

✅ Result

/fetch?url=http://localhost:5000/user/1

👉 ❌ Blocked

🧠 Key Insight

SSRF prevention is not just input validation — it requires network awareness.

🛡️ Fix 2 — Proper Authorization (Admin)

Approach

Replace client-controlled role with server-side validation:

token = request.headers.get("Authorization")

if token == "secret-admin-token":
    return "Welcome admin"

✅ Result

  • No token → Access denied
  • Valid token → Access granted

🧠 Key Insight

Authorization must always be enforced on the server side.

🛡️ Fix 3 — IDOR Protection

Approach

Ensure users can only access their own data.

if token != id:
    return "Unauthorized"

✅ Result

  • Own data → Allowed
  • Other users' data → Blocked

🧠 Key Insight

Every object access must be validated against user identity.

🔍 What This Project Taught Me

This project reinforced a few critical ideas:

1. Security is about assumptions

Every vulnerability came from a wrong assumption:

  • "User won't abuse URL input"
  • "User will only access their data"
  • "Headers can be trusted"

2. APIs fail in simple ways

No complex exploits needed:

  • Just changing a URL
  • Modifying a header
  • Calling internal endpoints

3. Fixing is harder than breaking

Writing vulnerable code is easy. Designing secure systems requires:

  • Input validation
  • Access control
  • Threat modeling

🚀 Final Thoughts

This lab was not about building a perfect system.

It was about understanding:

How APIs break
↓
How attackers think
↓
How to fix systems correctly

By combining:

  • SSRF
  • IDOR
  • Broken authorization

I now have a much clearer understanding of real-world API security risks.

🔗 Project Links