August 17, 2026
Belajar VAPT #1: Membongkar Data Rahasia dengan SQL Injection (PortSwigger Lab)
SQL Injection

By BIT Journal
4 min read
Overview & Scope Dalam arsitektur aplikasi web modern, Structured Query Language (SQL) adalah bahasa standar yang digunakan oleh server untuk berkomunikasi dengan database — mulai dari menyimpan, mengambil, hingga memperbarui data seperti informasi pengguna atau katalog produk.
Namun, ketika input dari pengguna dimasukkan langsung ke dalam perintah SQL tanpa adanya validasi atau pembersihan (sanitization), celah keamanan yang disebut SQL Injection (SQLi) dapat terjadi. Kerentanan ini memungkinkan penyerang (attacker) untuk "menyuntikkan" perintah SQL buatan sendiri, menginterupsi logika query asli, dan memediasi akses tidak sah ke dalam sistem database.
Untuk mempermudah pemahaman, dilakukan praktek pada lingkungan terkendali, yaitu lab yang disediakan oleh Portswigger untuk mempelajari kerentanan sistem. Pada pengujian ini, fokus utama dilakukan untuk mengevaluasi keamanan fitur filtering katalog produk pada aplikasi web e-commerce simulasi.
a. Target Halaman katalog produk PortSwigger Web Security Academy (Lab: SQL injection vulnerability in WHERE clause allowing retrieval of hidden data).
b. Fokus Pengujian Parameter category pada endpoint /filter.
c. Dampak Kerentanan Akses tidak sah ke data sensitif/internal (melihat produk yang belum dirilis ke publik).
Reconnaissance Tahap awal dimulai dengan mengeksplorasi fungsionalitas aplikasi secara normal. Saat menavigasi halaman utama, terdapat beberapa opsi kategori produk seperti Corporate gifts, Pets, dan Lifestyle.
Ketika salah satu kategori diklik, aplikasi mengirimkan request HTTP GET ke server dengan struktur URL seperti berikut:
GET /filter?category= Corporate+gifts HTTP/2
Dari hasil pengamatan alur aplikasi, diduga kuat bahwa server mengambil data produk dari database SQL dengan query yang logika dasarnya mirip seperti ini:
SELECT * FROM products WHERE category = 'Corporate gifts' AND released = 1
Query ini mengindikasikan dua hal: a. Server menyaring produk berdasarkan kategori yang dipilih user (category = 'Corporate gifts').
b. Server secara otomatis menyembunyikan produk yang belum siap dijual dengan memberikan kondisi released = 1.
Vulnerability Identification Untuk menguji apakah parameter category terisolasi dengan aman, saya mencegat (intercept) lalu lintas data langsung pada URL dan mencoba melakukan injeksi karakter khusus seperti petik satu ('). Ketika nilai parameter diubah menjadi Corporate gifts', aplikasi tidak menangani karakter tersebut dengan benar. Karakter petik satu sengaja dimasukkan untuk mematahkan sintaks SQL bawaan aplikasi (break out of the data context).
Karena tidak adanya sanitasi input atau penggunaan parameterized queries pada sisi backend, parameter ini terkonfirmasi rentan terhadap SQL Injection (SQLi). Hal ini membuka celah bagi attacker untuk menginterupsi logika query SQL asli dan menyisipkan perintah buatan sendiri.
Munculnya 500 Internal Server Error, terutama saat pengguna memasukkan karakter khusus seperti ', ", atau
a. Internal Server Error = Titik Awal Investigasi (Bukan Hasil Akhir)
Mendapatkan HTTP 500 berarti kamu sudah membentur celah (finding an entry point). Tugas kamu selanjutnya adalah menyesuaikan payload agar perintah buatanmu dapat dieksekusi dengan sukses tanpa membuat server crash (mengubah status respons dari 500 kembali ke 200 OK dengan hasil eksploitasi).
b. Dampak Tambahan (Verbose Error Message)
Kadang, selain HTTP 500, server yang tidak aman juga menampilkan pesan error detail di layar (misal: Uncaught SyntaxError: SQL state [42000] in PostgreSQL…). Ini disebut kerentanan Information Disclosure, yang memberikan petunjuk gratis kepada pentester/attacker tentang jenis database dan struktur kueri yang digunakan backend.
Exploitation (PoC) Setelah mengonfirmasi titik celahnya, langkah selanjutnya adalah menyusun payload SQL Injection untuk memanipulasi logika database agar menampilkan semua produk, termasuk yang berstatus released = 0.
Langkah Eksekusi:
- Tangkap request HTTP GET saat memilih kategori di Burp Suite Proxy.
- Modifikasi nilai parameter category pada bagian request body/URL dari Corporate gifts menjadi:
Corporate gifts' OR 1=1 —
- Forward request tersebut ke server.
Analisis Payload:
Ketika payload tersebut diproses, struktur query di backend berubah menjadi:
SELECT * FROM products WHERE category = 'Corporate gifts' OR 1=1 — ' AND released = 1
· Petik tunggal (') pertama berfungsi untuk menutup string parameter asli (Corporate gifts).
· OR 1=1 memberikan kondisi logika baru yang nilainya akan selalu benar (True), terlepas dari apakah nama kategorinya cocok atau tidak.
· Tanda — berfungsi sebagai karakter comment di SQL (PostgreSQL/SQLite/MySQL tergantung tipe DB). Karakter ini mematikan seluruh perintah setelahnya, sehingga syarat AND released = 1 diabaikan oleh database.
Hasil (Result):
Aplikasi merespons dengan menampilkan seluruh data produk yang ada di database pada halaman web. Sistem secara tidak langsung dipaksa membocorkan item-item rahasia/internal yang seharusnya belum tampil di katalog publik.
Remediation Kerentanan SQL Injection seperti ini sangat berbahaya jika ditemukan di lingkungan produksi karena dapat berujung pada kebocoran seluruh isi database.
Untuk menutup celah ini, tim pengembang disarankan melakukan perbaikan berikut:
a. Gunakan Prepared Statements (Parameterized Queries): Ini adalah solusi utama dan paling efektif. Jangan pernah menggabungkan input pengguna secara langsung (string concatenation) ke dalam query SQL. Gunakan placeholder agar database memperlakukan input pengguna murni sebagai data, bukan perintah kueri yang dapat dieksekusi.
Contoh perbaikan (Java/PHP/Node.js):
— Menggunakan parameterized query
SELECT * FROM products WHERE category = ? AND released = 1
b. Input Validation / Allow-listing: Terapkan validasi ketat di sisi server. Karena opsi kategori sudah ditentukan dari awal, server seharusnya hanya menerima input yang cocok dengan daftar kategori yang sah (allow-list).
c. Principle of Least Privilege: Pastikan akun database yang digunakan oleh aplikasi web hanya memiliki hak akses (privilege) sebatas yang dibutuhkan saja untuk meminimalkan dampak jika terjadi eksploitasi.