CODEBOOK
Website Platform Belajar Dan Edukasi
By Shadownex 2025-2026
← Kembali ke Katalog Lab
SQL InjectionUNSOLVEDReward: +200 XP

Lab 8: Time-based blind SQL injection in order status lookup endpoint

Endpoint pelacakan status pesanan tidak menampilkan error maupun data hasil kueri, namun penyerang dapat mengekstrak data menggunakan tunda waktu `SLEEP(3)`.

TARGET OBJECTIVE & BRIEFING

Objective:

Gunakan fungsi conditional boolean delay untuk mengekstrak string Flag karakter demi karakter berdasarkan tunda waktu eksekusi server.

Fitur lacak paket di e-commerce mengembalikan status generik "Pesanan Diproses" atau "Tidak Ditemukan". Meskipun tidak ada data yang bocor di layar, query SQL rentan terhadap Time-Based Blind Injection. Apabila ekspresi boolean tebakan Anda bernilai TRUE, fungsi `pg_sleep(3)` atau `SLEEP(3)` akan dieksekusi oleh server.

PENTESTING METHODOLOGY
1. Akses endpoint pelacak status pesanan.
2. Uji tunda waktu standar: `ORD1001' AND SLEEP(3)--`.
3. Amati bahwa respon HTTP mengalami tunda tepat 3 detik.
4. Konstruksikan script eksploitasi untuk menebak huruf Flag satu per satu: `ORD1001' AND IF(ASCII(SUBSTRING((SELECT flag FROM secret_keys),1,1))=67, SLEEP(3), 0)--`.
5. Rekonstruksi Flag penuh berdasarkan tunda waktu respon.
CODE SECURITY INSPECTION

Time-Based Blind SQLi mengeksploitasi perbedaan waktu respon server. Parameterized Queries sepenuhnya melumpuhkan fungsi seperti SLEEP() dari masukan pengguna.

VULNERABLE CODE

// KODE RENTAN (String Concatenation tanpa output error)
app.post('/api/order/status', (req, res) => {
  const { orderId } = req.body;
  // DANGEROUS: Permintaan dieksekusi langsung tanpa sanitasi
  const query = `SELECT status FROM orders WHERE order_id = '${orderId}'`;
  
  db.query(query, (err, rows) => {
    // Respon generik yang menyembunyikan error
    if (rows && rows.length > 0) return res.json({ status: rows[0].status });
    res.json({ status: 'Pesanan tidak ditemukan' });
  });
});

SECURE CODEBOOK IMPLEMENTATION

// KODE AMAN CODEBOOK STANDARD (Parameterized Query + Safe Error Handling)
app.post('/api/order/status', (req, res) => {
  const { orderId } = req.body;
  // SAFE: Parameterized Query
  const query = 'SELECT status FROM orders WHERE order_id = $1';
  
  db.query(query, [orderId], (err, rows) => {
    if (rows && rows.length > 0) return res.json({ status: rows[0].status });
    res.json({ status: 'Pesanan tidak ditemukan' });
  });
});