Skenario 23 / 26PASS
Broken Object Level Authorization - GraphQL - Transaction Summary
Lingkungan lab — bukan sistem produksi
Tangkapan layar dan trafik mentah tidak diterjemahkan; teks di dalamnya mungkin menggunakan bahasa lain.
vuln-bank/Evidence/[PASS] Broken Object Level Authorization - GraphQL - Transaction Summary
01 — Catatan
Catatan pengujian
Kerentanan
[PASS] Broken Object Level Authorization - GraphQL - Transaction Summary
Deskripsi
Pengujian berupaya membaca ringkasan transaksi milik pengguna lain melalui argumen accountNumber pada resolver GraphQL transactionSummary, termasuk rekening korban dan rekening administrator.
Dampak
Tidak ada dampak. Kontrol bertahan: resolver membandingkan accountNumber yang diminta dengan rekening milik pemegang token dan menolak permintaan lintas objek dengan galat eksplisit. Pengguna biasa hanya dapat membaca ringkasan transaksi rekeningnya sendiri.
Catatan: jalur kode yang sama tetap bermasalah bagi pemanggil dengan peran administrator, karena nilai argumen diteruskan ke query SQL tanpa parameterisasi; hal tersebut dilaporkan terpisah pada temuan SQL Injection - GraphQL.
CWE
CWE-639: Authorization Bypass Through User-Controlled Key
OWASP
A01:2021 - Broken Access Control
Skenario
Normal: pengguna biasa meminta ringkasan transaksi rekeningnya sendiri -> berhasil. Percobaan: accountNumber diganti dengan rekening korban -> ditolak. Percobaan: accountNumber diganti dengan rekening administrator -> ditolak.
Endpoint
POST http://127.0.0.1:5001/graphql
Fitur terdampak
GraphQL transactionSummary (otorisasi objek)
Rekomendasi perbaikan
- Pertahankan pemeriksaan kepemilikan rekening pada resolver.
- Lengkapi dengan parameterized query agar argumen yang sama tidak menjadi titik injeksi bagi pemanggil dengan hak lebih tinggi.
Bukti konsep
1) (Screenshot 1) NORMAL: pengguna biasa meminta ringkasan transaksi rekeningnya sendiri -> berhasil.
2) (Screenshot 2) PERCOBAAN: accountNumber diganti dengan rekening korban -> ditolak dengan galat You can only query your own transaction summary, kontrol bertahan.
3) (Screenshot 3) PERCOBAAN: accountNumber diganti dengan rekening administrator -> ditolak, kontrol bertahan.
Lihat catatan sumber (bahasa Indonesia)
Vulnerability:
[PASS] Broken Object Level Authorization - GraphQL - Transaction Summary
Description:
Pengujian berupaya membaca ringkasan transaksi milik pengguna lain melalui argumen accountNumber pada resolver GraphQL transactionSummary, termasuk rekening korban dan rekening administrator.
Impact:
Tidak ada dampak. Kontrol bertahan: resolver membandingkan accountNumber yang diminta dengan rekening milik pemegang token dan menolak permintaan lintas objek dengan galat eksplisit. Pengguna biasa hanya dapat membaca ringkasan transaksi rekeningnya sendiri.
Catatan: jalur kode yang sama tetap bermasalah bagi pemanggil dengan peran administrator, karena nilai argumen diteruskan ke query SQL tanpa parameterisasi; hal tersebut dilaporkan terpisah pada temuan SQL Injection - GraphQL.
CWE:
CWE-639: Authorization Bypass Through User-Controlled Key
OWASP:
A01:2021 - Broken Access Control
Scenario:
Normal: pengguna biasa meminta ringkasan transaksi rekeningnya sendiri -> berhasil. Percobaan: accountNumber diganti dengan rekening korban -> ditolak. Percobaan: accountNumber diganti dengan rekening administrator -> ditolak.
Endpoint:
POST http://127.0.0.1:5001/graphql
Affected Feature:
GraphQL transactionSummary (otorisasi objek)
Remediation:
- Pertahankan pemeriksaan kepemilikan rekening pada resolver.
- Lengkapi dengan parameterized query agar argumen yang sama tidak menjadi titik injeksi bagi pemanggil dengan hak lebih tinggi.
POC:
1) (Screenshot 1) NORMAL: pengguna biasa meminta ringkasan transaksi rekeningnya sendiri -> berhasil.
2) (Screenshot 2) PERCOBAAN: accountNumber diganti dengan rekening korban -> ditolak dengan galat You can only query your own transaction summary, kontrol bertahan.
3) (Screenshot 3) PERCOBAAN: accountNumber diganti dengan rekening administrator -> ditolak, kontrol bertahan.
02 — Tangkapan layar
Tangkapan layar (3)
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
POST /graphql 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-Type: application/json
Content-Length: 148
{"query": "query($a:String){transactionSummary(accountNumber:$a,limit:3){scope accountNumber totalTransactions}}", "variables": {"a": "0932191785"}}HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 149
Access-Control-Allow-Origin: *
Server: Werkzeug/2.0.1 Python/3.9.25
Date: Wed, 30 Sep 2026 03:13:13 GMT
{
"data": {
"transactionSummary": {
"accountNumber": "0932191785",
"scope": "account",
"totalTransactions": 11
}
}
}REKAMAN 02 / 2
POST /graphql 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-Type: application/json
Content-Length: 148
{"query": "query($a:String){transactionSummary(accountNumber:$a,limit:3){scope accountNumber totalTransactions}}", "variables": {"a": "9159912486"}}HTTP/1.1 400 BAD REQUEST
Content-Type: application/json
Content-Length: 361
Access-Control-Allow-Origin: *
Server: Werkzeug/2.0.1 Python/3.9.25
Date: Wed, 30 Sep 2026 03:13:14 GMT
{
"data": {
"transactionSummary": null
},
"errors": [
{
"message": "You can only query your own transaction summary.\n\nGraphQL request:1:18\n1 | query($a:String){transactionSummary(accountNumber:$a,limit:3){scope accountNumber totalTransactions}}\n | ^",
"path": [
"transactionSummary"
]
}
]
}REKAMAN 03 / 3
POST /graphql 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-Type: application/json
Content-Length: 146
{"query": "query($a:String){transactionSummary(accountNumber:$a,limit:3){scope accountNumber totalTransactions}}", "variables": {"a": "ADMIN001"}}HTTP/1.1 400 BAD REQUEST
Content-Type: application/json
Content-Length: 361
Access-Control-Allow-Origin: *
Server: Werkzeug/2.0.1 Python/3.9.25
Date: Wed, 30 Sep 2026 03:13:15 GMT
{
"data": {
"transactionSummary": null
},
"errors": [
{
"message": "You can only query your own transaction summary.\n\nGraphQL request:1:18\n1 | query($a:String){transactionSummary(accountNumber:$a,limit:3){scope accountNumber totalTransactions}}\n | ^",
"path": [
"transactionSummary"
]
}
]
}