CODEBOOK
Website Platform Belajar Dan Edukasi
By Shadownex 2025-2026
← Kembali ke Katalog Lab
Broken Access ControlUNSOLVEDReward: +100 XP

Lab 10: Insecure Direct Object Reference (IDOR) on confidential invoice download

Service penunduhan faktur transaksi mengandalkan parameter ID numerik tanpa melakukan verifikasi kepemilikan data pengguna yang terautentikasi.

TARGET OBJECTIVE & BRIEFING

Objective:

Ganti ID faktur pada parameter URL dari `1042` ke ID faktur rahasia milik pengguna lain (`1001`) untuk mengakses dokumen finansial terlarang.

Sistem penagihan invoice Apex Finance menyediakan endpoint pengunduhan faktur `/api/invoice/download?id=1042`. Meskipun pengguna wajib login, backend hanya mengambil data faktur berdasarkan ID tanpa memeriksa apakah ID pengguna yang login cocok dengan pemilik faktur tersebut.

PENTESTING METHODOLOGY
1. Login sebagai akun pengguna biasa.
2. Klik tombol "Unduh Invoice Saya" dan amati parameter URL `id=1042`.
3. Ubah nilai parameter `id` menjadi `1001` (ID invoice eksekutif perusahaan).
4. Aplikasi mengembalikan file PDF invoice rahasia yang berisi Flag Verifikasi.
CODE SECURITY INSPECTION

IDOR terjadi akibat kegagalan otorisasi di tingkat objek (Broken Object Level Authorization). CodeBook memverifikasi hak kepemilikan record data pada setiap kueri.

VULNERABLE CODE

// KODE RENTAN (Missing Authorization Check)
app.get('/api/invoice/download', isAuth, async (req, res) => {
  const { id } = req.query;
  // DANGEROUS: Mengambil data tanpa memverifikasi milik siapa invoice ini!
  const invoice = await Invoice.findById(id);
  if (!invoice) return res.status(404).send('Invoice tidak ditemukan');
  res.json({ invoiceData: invoice });
});

SECURE CODEBOOK IMPLEMENTATION

// KODE AMAN CODEBOOK STANDARD (Data Ownership Verification)
app.get('/api/invoice/download', isAuth, async (req, res) => {
  const { id } = req.query;
  const invoice = await Invoice.findById(id);
  if (!invoice) return res.status(404).send('Invoice tidak ditemukan');
  
  // SAFE: Cek apakah invoice ini milik user yang sedang terautentikasi (atau role admin)
  if (invoice.userId !== req.user.id && req.user.role !== 'admin') {
    return res.status(403).json({ error: 'Akses ditolak: Anda bukan pemilik invoice ini' });
  }
  res.json({ invoiceData: invoice });
});