Jawaban lainnya sudah mencakup apa yang perlu Anda ketahui. Tapi mungkin membantu untuk menjelaskan lebih lanjut:
Ada DUA HAL yang perlu Anda lakukan:
1. Validasi data formulir.
Seperti yang ditunjukkan oleh jawaban Jonathan Hobbs dengan sangat jelas, pilihan elemen html untuk input formulir tidak melakukan pemfilteran yang dapat diandalkan untuk Anda.
Validasi biasanya dilakukan dengan cara yang tidak mengubah data, tetapi menampilkan formulir lagi, dengan kolom yang ditandai sebagai "Harap perbaiki ini".
Sebagian besar framework dan CMS memiliki pembuat formulir yang membantu Anda melakukan tugas ini. Dan tidak hanya itu, mereka juga membantu melawan CSRF (atau "XSRF"), yang merupakan bentuk serangan lain.
2. Sanitasi / Escape variabel dalam pernyataan SQL ..
.. atau biarkan pernyataan yang telah disiapkan melakukan pekerjaan untuk Anda.
Jika Anda membuat pernyataan SQL (Saya) dengan variabel apa pun, disediakan pengguna atau tidak, Anda perlu keluar dan mengutip variabel ini.
Secara umum, variabel apa pun yang Anda masukkan ke dalam pernyataan MySQL harus berupa string, atau sesuatu yang dapat diubah PHP dengan andal menjadi string yang dapat dicerna oleh MySQL. Seperti, angka.
Untuk string, Anda kemudian perlu memilih salah satu dari beberapa metode untuk melarikan diri dari string, yang berarti, ganti karakter apa pun yang akan memiliki efek samping di MySQL.
- Di MySQL + PHP sekolah lama, mysql_real_escape_string () melakukan pekerjaan itu. Masalahnya adalah terlalu mudah untuk dilupakan, jadi Anda harus benar-benar menggunakan pernyataan yang sudah disiapkan atau pembuat kueri.
- Di MySQLi, Anda dapat menggunakan pernyataan yang telah disiapkan.
- Sebagian besar framework dan CMS menyediakan pembuat kueri yang membantu Anda dalam tugas ini.
Jika Anda berurusan dengan angka, Anda dapat menghilangkan escaping dan tanda kutip (inilah mengapa pernyataan yang disiapkan memungkinkan untuk menentukan tipe).
Penting untuk diketahui bahwa Anda keluar dari variabel untuk pernyataan SQL, dan BUKAN untuk database itu sendiri . Basis data akan menyimpan string asli, tetapi pernyataan tersebut membutuhkan versi lolos.
Apa yang terjadi jika Anda menghilangkan salah satunya?
Jika Anda tidak menggunakan validasi formulir , tetapi Anda membersihkan input SQL, Anda mungkin melihat semua jenis hal buruk terjadi, tetapi Anda tidak akan melihat injeksi SQL! (*)
Pertama, ini dapat membuat aplikasi Anda menjadi status yang tidak Anda rencanakan. Misalnya, jika Anda ingin menghitung usia rata-rata semua pengguna, tetapi satu pengguna memberikan "aljkdfaqer" untuk usia tersebut, penghitungan Anda akan gagal.
Kedua, mungkin ada semua jenis serangan injeksi lain yang perlu Anda pertimbangkan: Misalnya input pengguna dapat berisi javascript atau hal lain.
Masih ada masalah dengan database: Misalnya jika sebuah field (kolom tabel database) dibatasi hingga 255 karakter, dan stringnya lebih panjang dari itu. Atau jika bidang hanya menerima angka, dan Anda mencoba menyimpan string non-numerik sebagai gantinya. Tapi ini bukan "injeksi", ini hanya "merusak aplikasi".
Tetapi, bahkan jika Anda memiliki bidang teks bebas di mana Anda mengizinkan masukan apa pun tanpa validasi sama sekali, Anda masih dapat menyimpan ini ke database begitu saja, jika Anda meloloskan diri dengan benar saat masuk ke pernyataan database. Masalahnya muncul saat Anda ingin menggunakan string ini di suatu tempat.
(*) atau ini akan menjadi sesuatu yang sangat eksotis.
Jika Anda tidak melarikan diri dari variabel untuk pernyataan SQL , tetapi Anda memvalidasi input formulir, Anda masih dapat melihat hal-hal buruk terjadi.
Pertama, Anda berisiko bahwa saat Anda menyimpan data ke database dan memuatnya lagi, itu tidak akan menjadi data yang sama lagi, "hilang dalam terjemahan".
Kedua, ini dapat menghasilkan pernyataan SQL yang tidak valid, dan dengan demikian membuat aplikasi Anda mogok. Misalnya, jika ada variabel yang berisi karakter kutipan atau kutipan ganda, tergantung jenis kutipan yang Anda gunakan, Anda akan mendapatkan pernyataan MySQL yang tidak valid.
Ketiga, masih dapat menyebabkan injeksi SQL.
Jika masukan pengguna Anda dari formulir sudah difilter / divalidasi, injeksi SQl yang disengaja mungkin menjadi kecil kemungkinannya, JIKA masukan Anda dikurangi menjadi daftar opsi yang di-hardcode, atau jika dibatasi untuk angka. Tetapi input teks bebas apa pun dapat digunakan untuk injeksi SQL, jika Anda tidak meng-escape dengan benar variabel dalam pernyataan SQL.
Dan bahkan jika Anda tidak memiliki masukan formulir sama sekali, Anda masih dapat memiliki string dari semua jenis sumber: Membaca dari sistem file, menyalin dari internet, dll. Tidak ada yang dapat menjamin bahwa string ini aman.
<select>
masukan Anda . Bahkan pengguna yang sedikit teknis dapat menambahkan opsi tambahan menggunakan konsol browser. jika Anda menyimpan daftar putih array dari nilai-nilai yang tersedia dan membandingkan input dengannya, Anda dapat menguranginya (dan Anda harus melakukannya karena itu mencegah nilai yang tidak diinginkan)