flawopen.com/SQL Injection/Apakah escaping cukup?
Apakah Escape Tanda Kutip Mencegah SQL Injection?
Biasanya tidak. Fungsi escaping bergantung pada database, character set koneksi, mode SQL, dan konteks tanda kutip yang tepat. Kueri berparameter menjaga nilai terpisah dari sintaks SQL melalui API driver. Gunakan parameter untuk nilai; pilih identifier dinamis yang tidak dapat diikat dari allowlist tetap milik aplikasi.
Mengapa escaping rapuh dalam praktik
Escaping bukan penggantian teks yang bebas konteks. MySQL mendokumentasikan bahwa mysql_real_escape_string() memakai character set koneksi dan SET NAMES tidak memperbarui state library klien yang digunakan fungsi tersebut. Ketidakcocokan dapat membatalkan asumsi atas teks yang di-escape. Utamakan API berparameter; jika kode lama masih memerlukan escaping, gunakan fungsi driver yang didukung untuk mengatur charset dan tangani error.
Escaping harus diterapkan dengan benar pada setiap interpolasi, sesuai driver, character set, mode SQL, dan konteks literal. API berparameter memperjelas pemisahan nilai dan data saat pemanggilan kueri serta menghindari perakitan string bertanda kutip secara manual.
Escape tanda kutip hanya menangani karakter dalam literal string tertentu. Ini tidak membentuk nama tabel/kolom, kata kunci, atau arah pengurutan dengan aman, dan tidak melindungi input dalam ekspresi numerik tanpa tanda kutip. Ikat nilai sebagai parameter dan petakan struktur SQL dinamis ke opsi tetap milik aplikasi.
// Input pengguna disisipkan ke sintaks SQL
query = f"SELECT id FROM users WHERE name = '{name}'"
cursor.execute(query)
// Driver mengikat name sebagai nilai data
cursor.execute(
"SELECT id FROM users WHERE name = ?",
(name,),
)
Perbedaan yang diberikan pengikatan parameter
Kueri berparameter mengirim struktur SQL dan nilai sebagai masukan terpisah melalui API database. Driver dapat memakai prepared statement native atau implementasi aman lain; jangan mengasumsikan urutan protokol tertentu. Sifat keamanannya adalah nilai diperlakukan sebagai data, bukan diurai ulang sebagai sintaks SQL. Pada Python DB-API, gunakan placeholder driver dan kirim nilai secara terpisah; jangan membuat kueri dengan format string.
Daftar periksa rekayasa
- ✓Ikat setiap nilai data yang dikendalikan pengguna melalui API driver; jangan format ke dalam teks SQL.
- ✓Pilih nama tabel, kolom, dan pengurutan dinamis dari allowlist tetap milik aplikasi.
- ✓Jika escaping lama belum dapat dihapus, gunakan API driver sesuai konteks dan verifikasi character set koneksi serta mode SQL.
- ✓Uji konstruksi kueri dengan tanda kutip, teks non-ASCII, dan identifier tidak valid tanpa mengirim pernyataan destruktif.
Pertanyaan umum
Untuk identifier atau fragmen SQL yang tidak dapat diikat, gunakan hanya API quoting yang didukung driver bersama allowlist tetap milik aplikasi. Jangan gunakan escaping umum pada nilai sembarang.
Fungsi itu dapat membantu dalam konteks yang didokumentasikan, tetapi tetap bergantung pada database, setelan koneksi, konteks quoting, dan penggunaan tepat di setiap lokasi. Kueri berparameter tetap menjadi pilihan default yang lebih aman untuk nilai.
Referensi
- OWASP — panduan pencegahan SQL Injection
- CWE-89 — SQL Injection
- Manual PHP — mysqli::real_escape_string
- MySQL C API — mysql_real_escape_string
- flawopen.com — SQL Injection (semua bahasa)