Pendahuluan
Bayangkan Anda membangun sebuah aplikasi web. Halamannya rapi, fiturnya lengkap, dan semuanya berjalan normal. Tapi di balik itu semua, ada satu celah kecil yang tidak terlihat celah yang bisa membuat seluruh isi database Anda bocor dalam hitungan menit, bahkan detik.
Itulah SQL Injection.
Serangan ini bukan hal baru. Sudah ada sejak akhir 1990-an, tapi sampai sekarang masih konsisten masuk OWASP Top 10 daftar sepuluh kerentanan web paling berbahaya yang dirilis oleh Open Web Application Security Project. Artinya, meski sudah dikenal luas selama puluhan tahun, celah ini masih terus ditemukan di aplikasi-aplikasi yang berjalan hari ini.
Kasus nyatanya tidak sedikit. Pada 2008, serangan SQL Injection menjadi salah satu metode utama dalam pembobolan data Heartland Payment Systems yang berdampak pada lebih dari 130 juta data kartu kredit. Bukan karena sistemnya asal-asalan tapi karena satu celah kecil pada input yang tidak divalidasi dengan benar.
Di artikel ini saya tidak hanya menjelaskan teori. Saya melakukan eksperimen langsung menggunakan DVWA (Damn Vulnerable Web Application) di lingkungan lokal untuk membuktikan bagaimana serangan ini bekerja, apa dampaknya, dan yang paling penting bagaimana cara mencegahnya.
Apa Itu SQL Injection?
SQL Injection terjadi ketika penyerang menyisipkan kode SQL berbahaya ke dalam input yang dikirim ke aplikasi web. Kalau aplikasinya tidak memvalidasi input dengan benar, kode tersebut ikut dieksekusi oleh database dan hasilnya bisa sangat merusak.
Supaya lebih konkret, lihat contoh ini. Misalnya ada form pencarian user dengan query seperti berikut:
SELECT * FROM users WHERE id = '$input';Dalam kondisi normal, kalau pengguna memasukkan angka 1, query yang dijalankan jadi:
SELECT * FROM users WHERE id = '1';Tidak ada masalah. Tapi kalau penyerang mengisi input dengan:
' OR '1'='1Query yang terbentuk berubah menjadi:
SELECT * FROM users WHERE id = '' OR '1'='1';Kondisi '1'='1' selalu bernilai true. Akibatnya, query ini mengembalikan semua baris di tabel bukan hanya satu user, tapi seluruh isi database.
Intinya: SQL Injection terjadi bukan karena databasenya lemah, tapi karena aplikasi memperlakukan input pengguna sebagai bagian dari perintah SQL, bukan sebagai data biasa.
Kenapa Masih Relevan Sampai Sekarang?
OWASP secara konsisten menempatkan Injection di jajaran teratas daftar kerentanan web paling berbahaya. Alasannya sederhana celah ini mudah dieksploitasi bahkan oleh pemula, dampaknya bisa sangat besar mulai dari kebocoran data hingga penghapusan seluruh database, dan masih banyak aplikasi yang dibangun tanpa validasi input yang memadai.
Eksperimen: Membuktikan SQL Injection Secara Langsung
Untuk memahami SQL Injection secara mendalam, saya melakukan eksperimen menggunakan DVWA (Damn Vulnerable Web Application) yang dijalankan secara lokal dengan XAMPP. DVWA adalah aplikasi web yang sengaja dibuat rentan, dirancang khusus untuk keperluan belajar dan pengujian keamanan.
Setup Environment
Sebelum eksperimen dimulai, berikut environment yang digunakan:
- OS: Windows 11
- Web Server: Apache (via XAMPP)
- Database: MariaDB 10.4.32
- Tools: DVWA, browser Chrome
- Security Level DVWA: Low
Setelah XAMPP aktif dan DVWA berhasil dikonfigurasi, langkah pertama adalah login ke DVWA dengan kredensial default, lalu mengatur security level ke Low agar semua celah keamanan tidak difilter sama sekali.

Eksperimen 1: Input Normal
Pertama, saya memasukkan input normal berupa angka 1 ke kolom User ID untuk melihat bagaimana aplikasi bekerja dalam kondisi wajar.
Input: 1Hasilnya aplikasi mengembalikan satu data user:
ID: 1
First name: admin
Surname: admin
Ini perilaku yang diharapkan satu input, satu output yang sesuai.
Eksperimen 2: Deteksi Kerentanan
Langkah berikutnya adalah menguji apakah aplikasi rentan dengan memasukkan tanda petik tunggal:
Input: 'Hasilnya langsung muncul error SQL yang cukup mengejutkan:
Fatal error: Uncaught mysqli_sql_exception:
You have an error in your SQL syntax...
Error ini mengonfirmasi dua hal sekaligus: pertama, input langsung dimasukkan ke dalam query SQL tanpa sanitasi apapun. Kedua, aplikasi menampilkan error database secara terbuka ke browser yang di dunia nyata memberi informasi berharga bagi penyerang tentang struktur query yang digunakan.
Eksperimen 3: Dump Seluruh Data User
Setelah tahu aplikasi rentan, saya mencoba payload klasik SQL Injection:
Input: ' OR '1'='1Hasilnya mengejutkan bukan satu user yang muncul, tapi seluruh isi tabel users:
First name: admin | Surname: admin
First name: Gordon | Surname: Brown
First name: Hack | Surname: Me
First name: Pablo | Surname: Picasso
First name: Bob | Surname: Smith
Dengan satu baris input, seluruh data pengguna berhasil diekstrak. Query yang seharusnya mengembalikan satu baris kini mengembalikan semua baris karena kondisi '1'='1' selalu bernilai true.
Eksperimen 4: Mengekstrak Informasi Database (UNION Attack)
Selanjutnya saya mencoba teknik UNION-based injection untuk mengekstrak informasi lebih dalam tentang server:
Input: ' UNION SELECT null, version()-- -Hasilnya server langsung menampilkan versi database yang digunakan:
Surname: 10.4.32-MariaDB
Di skenario nyata, informasi versi database seperti ini sangat berguna bagi penyerang untuk mencari eksploit atau kelemahan spesifik yang ada di versi tersebut.
Eksperimen 5: Mengekstrak Username dan Password Hash
Eksperimen terakhir dan yang paling berbahaya mengekstrak langsung username beserta hash password dari tabel users:
Input: ' UNION SELECT user, password FROM users-- -Hasilnya semua kredensial pengguna berhasil diekstrak:
admin : 5f4dcc3b5aa765d61d8327deb882cf99
gordonb : e99a18c428cb38d5f260853678922e03
1337 : 8d3533d75ae2c3966d7e0d4fcc69216b
pablo : 0d107d09f5bbe40cade3de5c71e9e9b7
smithy : 5f4dcc3b5aa765d61d8327deb882cf99
Hash-hash ini menggunakan algoritma MD5 yang sudah dianggap lemah. Dengan tools seperti hashcat atau bahkan situs online seperti crackstation.net, hash MD5 sederhana bisa di-crack dalam hitungan detik. Artinya, dari celah SQL Injection saja, penyerang bisa mendapatkan akses penuh ke seluruh akun pengguna.
Dampak SQL Injection
Dari eksperimen yang sudah dilakukan, terlihat jelas betapa berbahayanya celah ini. Tapi di dunia nyata, dampaknya jauh lebih serius dari sekadar menampilkan data di layar lab.
1. Kebocoran Data
Ini yang paling umum terjadi. Penyerang bisa mengekstrak seluruh isi database nama pengguna, email, nomor telepon, alamat, hingga data kartu kredit. Kasus Heartland Payment Systems yang disebutkan di pendahuluan adalah contoh nyata bagaimana satu celah SQL Injection bisa berdampak pada ratusan juta data pengguna.
2. Bypass Autentikasi
Dengan SQL Injection, penyerang bisa masuk ke sistem tanpa mengetahui password sama sekali. Cukup dengan memanipulasi query login, sistem akan menganggap autentikasi berhasil. Ini berarti halaman admin, dashboard internal, atau panel sensitif apapun bisa diakses tanpa kredensial yang valid.
3. Manipulasi dan Penghapusan Data
Bukan hanya membaca data, SQL Injection juga bisa digunakan untuk mengubah atau menghapus data. Bayangkan seluruh tabel users di database produksi terhapus sekaligus tanpa backup, itu berarti kehilangan data permanen.
4. Eskalasi Akses ke Server
Di konfigurasi tertentu, SQL Injection bisa digunakan untuk membaca file sistem atau bahkan mengeksekusi perintah di server. Dari celah di form input biasa, penyerang bisa bergerak menuju kendali penuh atas server.
Cara Pencegahan dan Mitigasi
Kabar baiknya, SQL Injection sebenarnya mudah dicegah kalau tahu caranya. Berikut pendekatan yang harus diterapkan.
1. Gunakan Prepared Statements (Parameterized Query)
Ini cara paling efektif. Dengan prepared statements, input pengguna tidak pernah langsung digabungkan ke dalam query SQL melainkan diperlakukan sebagai parameter terpisah yang tidak bisa mengubah struktur query.
Kode rentan (tanpa prepared statements):
// BERBAHAYA - input langsung digabung ke query
$id = $_GET['id'];
$query = "SELECT * FROM users WHERE id = '$id'";
$result = mysqli_query($conn, $query);Kode aman (dengan prepared statements):
// AMAN - input diperlakukan sebagai parameter
$id = $_GET['id'];
$stmt = $conn->prepare("SELECT * FROM users WHERE id = ?");
$stmt->bind_param("s", $id);
$stmt->execute();
$result = $stmt->get_result();Perbedaannya mendasar. Pada kode yang rentan, kalau $id berisi ' OR '1'='1, string itu langsung masuk ke query dan dieksekusi. Pada prepared statements, input apapun yang masuk hanya diperlakukan sebagai nilai string biasa bukan sebagai bagian dari perintah SQL.
2. Validasi dan Sanitasi Input
Jangan pernah percaya input dari pengguna. Terapkan validasi di sisi server untuk memastikan input sesuai format yang diharapkan.
// Contoh validasi sederhana untuk input angka
$id = $_GET['id'];
if (!is_numeric($id)) {
die("Input tidak valid.");
}
// Lanjutkan query hanya kalau input valid
$stmt = $conn->prepare("SELECT * FROM users WHERE id = ?");
$stmt->bind_param("i", $id);
$stmt->execute();3. Sembunyikan Pesan Error Database
Dari eksperimen tadi, ketika saya memasukkan tanda petik tunggal, error database langsung muncul di browser. Ini memberi informasi berharga kepada penyerang. Di lingkungan produksi, pesan error teknis tidak boleh ditampilkan ke pengguna.
// Matikan display_errors di production
ini_set('display_errors', 0);
error_reporting(0);
// Log error ke file, bukan ke browser
ini_set('log_errors', 1);
ini_set('error_log', '/path/to/error.log');4. Terapkan Prinsip Least Privilege
User database yang digunakan aplikasi sebaiknya hanya punya izin yang benar-benar dibutuhkan. Kalau aplikasi hanya perlu membaca data, jangan beri izin DELETE atau DROP.
-- Buat user khusus untuk aplikasi dengan privilege minimal
CREATE USER 'app_user'@'localhost' IDENTIFIED BY 'strong_password';
-- Hanya beri akses SELECT dan INSERT, tidak lebih
GRANT SELECT, INSERT ON myapp_db.* TO 'app_user'@'localhost';
FLUSH PRIVILEGES;Dengan cara ini, meskipun penyerang berhasil mengeksploitasi SQL Injection, kerusakan yang bisa dilakukan tetap terbatas.
5. Gunakan Web Application Firewall (WAF)
WAF bisa mendeteksi dan memblokir pola serangan SQL Injection sebelum sampai ke aplikasi. Ini bukan pengganti praktik coding yang aman, tapi lapisan pertahanan tambahan yang berguna.
Kesimpulan
SQL Injection adalah salah satu celah keamanan web yang sudah lama dikenal tapi nyatanya masih terus ditemukan sampai sekarang. Dari eksperimen yang saya lakukan menggunakan DVWA, terbukti bahwa dengan input sesederhana ' OR '1'='1, seluruh data pengguna bisa diekstrak tanpa perlu akses khusus apapun. Bahkan lebih jauh, versi database dan hash password semua user bisa didapat hanya dengan beberapa baris payload SQL.
Yang membuat SQL Injection berbahaya bukan hanya dampaknya yang besar, tapi juga betapa mudahnya celah ini muncul seringkali hanya karena kebiasaan menulis query tanpa memikirkan input yang datang dari luar.
Tapi pencegahannya juga tidak rumit. Prepared statements saja sudah cukup untuk menutup sebagian besar celah SQL Injection. Ditambah validasi input, penyembunyian pesan error, dan prinsip least privilege, aplikasi yang kita bangun akan jauh lebih sulit untuk dieksploitasi.
Referensi
- OWASP Foundation. SQL Injection. https://owasp.org/www-community/attacks/SQL_Injection
- PortSwigger Web Security Academy. SQL Injection. https://portswigger.net/web-security/sql-injection
- DVWA (Damn Vulnerable Web Application). https://github.com/digininja/DVWA
- PHP Documentation. Prepared Statements and Stored Procedures. https://www.php.net/manual/en/pdo.prepared-statements.php
- OWASP. OWASP Top Ten. https://owasp.org/www-project-top-ten/
- Stuttard, D., & Pinto, M. The Web Application Hacker's Handbook. Wiley, 2011.