Artikel ini difokuskan untuk memberikan panduan yang jelas, sederhana, dan dapat ditindaklanjuti untuk mencegah kelemahan SQL Injection pada aplikasi Anda. Sayangnya, serangan SQL Injection sangat umum terjadi, dan ini disebabkan oleh dua faktor Show
Cacat SQL Injection diperkenalkan ketika pengembang perangkat lunak membuat kueri basis data dinamis yang dibangun dengan rangkaian string yang menyertakan input yang disediakan pengguna. Untuk menghindari kelemahan injeksi SQL itu sederhana. Pengembang juga perlu. a) berhenti menulis kueri dinamis dengan penggabungan string; Artikel ini menyediakan sekumpulan teknik sederhana untuk mencegah kerentanan SQL Injection dengan menghindari dua masalah ini. Teknik-teknik ini dapat digunakan dengan hampir semua jenis bahasa pemrograman dengan semua jenis database. Ada jenis database lain, seperti database XML, yang dapat memiliki masalah serupa (mis. g. , XPath dan injeksi XQuery) dan teknik ini juga dapat digunakan untuk melindunginya Pertahanan Primer
Pertahanan Tambahan
Contoh Tidak Aman Cacat injeksi SQL biasanya terlihat seperti ini Contoh (Java) berikut adalah UNSAFE, dan akan memungkinkan penyerang menyuntikkan kode ke dalam kueri yang akan dijalankan oleh database. Parameter "customerName" yang tidak divalidasi yang hanya ditambahkan ke kueri memungkinkan penyerang memasukkan kode SQL apa pun yang mereka inginkan. Sayangnya, metode untuk mengakses database ini terlalu umum
Pertahanan PrimerOpsi Pertahanan 1. Pernyataan yang Disiapkan (dengan Kueri Parameter)Penggunaan pernyataan yang disiapkan dengan pengikatan variabel (alias kueri berparameter) adalah bagaimana semua pengembang pertama-tama harus diajari cara menulis kueri basis data. Mereka sederhana untuk ditulis, dan lebih mudah dipahami daripada kueri dinamis. Kueri berparameter memaksa pengembang untuk terlebih dahulu menentukan semua kode SQL, lalu meneruskan setiap parameter ke kueri nanti. Gaya pengkodean ini memungkinkan database untuk membedakan antara kode dan data, terlepas dari masukan pengguna apa yang diberikan Pernyataan yang disiapkan memastikan bahwa penyerang tidak dapat mengubah maksud kueri, bahkan jika perintah SQL dimasukkan oleh penyerang. Dalam contoh aman di bawah ini, jika penyerang memasukkan ID pengguna 8, kueri berparameter tidak akan rentan dan akan mencari nama pengguna yang benar-benar cocok dengan seluruh string 8Rekomendasi khusus bahasa
Dalam keadaan yang jarang terjadi, pernyataan yang disiapkan dapat merusak kinerja. Ketika dihadapkan dengan situasi ini, yang terbaik adalah a) memvalidasi semua data dengan kuat atau b) melarikan diri dari semua input yang disediakan pengguna menggunakan rutinitas pelolosan khusus untuk vendor database Anda seperti yang dijelaskan di bawah ini, daripada menggunakan pernyataan yang disiapkan Contoh Pernyataan yang Disiapkan Java Aman Contoh kode berikut menggunakan _5, implementasi Java dari kueri berparameter, untuk mengeksekusi kueri basis data yang sama _C# aman. Contoh Pernyataan Disiapkan NET Dengan. NET, bahkan lebih mudah. Pembuatan dan eksekusi kueri tidak berubah. Yang harus Anda lakukan hanyalah meneruskan parameter ke kueri menggunakan panggilan 6 seperti yang ditunjukkan di sini
Kami telah menunjukkan contoh di Jawa dan. NET tetapi hampir semua bahasa lain, termasuk Cold Fusion, dan Classic ASP, mendukung antarmuka kueri berparameter. Bahkan lapisan abstraksi SQL, seperti Hibernate Query Language (HQL) memiliki jenis masalah injeksi yang sama (yang kami sebut Injeksi HQL). HQL juga mendukung kueri berparameter, sehingga kami dapat menghindari masalah ini Hibernate Query Language (HQL) Disiapkan Pernyataan (Parameter Bernama) Contoh
Untuk contoh kueri berparameter dalam bahasa lain, termasuk Ruby, PHP, Cold Fusion, dan Perl, lihat Cheat Sheet Parameterisasi Kueri atau situs ini Pengembang cenderung menyukai pendekatan Pernyataan Disiapkan karena semua kode SQL tetap berada di dalam aplikasi. Ini membuat aplikasi Anda relatif independen dari basis data Opsi Pertahanan 2. Prosedur TersimpanProsedur tersimpan tidak selalu aman dari injeksi SQL. Namun, konstruksi pemrograman prosedur tersimpan standar tertentu memiliki efek yang sama seperti penggunaan kueri berparameter saat diterapkan dengan aman yang merupakan norma untuk sebagian besar bahasa prosedur tersimpan Mereka membutuhkan pengembang untuk hanya membangun pernyataan SQL dengan parameter yang secara otomatis berparameter kecuali pengembang melakukan sesuatu yang sebagian besar di luar norma. Perbedaan antara pernyataan yang disiapkan dan prosedur tersimpan adalah bahwa kode SQL untuk prosedur tersimpan ditentukan dan disimpan dalam database itu sendiri, dan kemudian dipanggil dari aplikasi. Kedua teknik ini memiliki keefektifan yang sama dalam mencegah injeksi SQL sehingga organisasi Anda harus memilih pendekatan mana yang paling masuk akal bagi Anda Catatan. "Diimplementasikan dengan aman" berarti prosedur tersimpan tidak menyertakan pembuatan SQL dinamis yang tidak aman. Pengembang biasanya tidak menghasilkan SQL dinamis di dalam prosedur tersimpan. Namun, itu bisa dilakukan, tetapi harus dihindari. Jika tidak dapat dihindari, prosedur tersimpan harus menggunakan validasi input atau pelolosan yang tepat seperti yang dijelaskan dalam artikel ini untuk memastikan bahwa semua input yang diberikan pengguna ke prosedur tersimpan tidak dapat digunakan untuk menyuntikkan kode SQL ke dalam kueri yang dibuat secara dinamis. Auditor harus selalu mencari penggunaan 7, 8 atau 9 dalam prosedur tersimpan SQL Server. Pedoman audit serupa diperlukan untuk fungsi serupa untuk vendor lainAda juga beberapa kasus di mana prosedur tersimpan dapat meningkatkan risiko. Misalnya, di server MS SQL, Anda memiliki 3 peran default utama. 0, 1 dan 2. Sebelum prosedur tersimpan mulai digunakan, DBA akan memberikan hak db_datareader atau db_datawriter kepada pengguna layanan web, tergantung pada persyaratan. Namun, prosedur tersimpan memerlukan hak eksekusi, peran yang tidak tersedia secara default. Beberapa pengaturan di mana manajemen pengguna terpusat, tetapi terbatas pada 3 peran tersebut, menyebabkan semua aplikasi web berjalan di bawah hak db_owner sehingga prosedur tersimpan dapat berfungsi. Secara alami, itu berarti bahwa jika server dibobol, penyerang memiliki hak penuh atas database, di mana sebelumnya mereka mungkin hanya memiliki akses baca.Contoh Prosedur Tersimpan Java yang Aman Contoh kode berikut menggunakan _3, implementasi Java dari interface stored procedure, untuk mengeksekusi query database yang sama. Prosedur tersimpan _4 harus ditentukan sebelumnya dalam database dan menerapkan fungsi yang sama seperti kueri yang ditentukan di atas
VB aman. Contoh Prosedur Tersimpan .NET Contoh kode berikut menggunakan 5,. Implementasi NET dari interface stored procedure, untuk mengeksekusi query database yang sama. Prosedur tersimpan _4 harus ditentukan sebelumnya dalam database dan menerapkan fungsi yang sama seperti kueri yang ditentukan di atas
Opsi Pertahanan 3. Validasi Input daftar yang diizinkanBerbagai bagian kueri SQL bukan merupakan lokasi yang sah untuk penggunaan variabel ikat, seperti nama tabel atau kolom, dan indikator tata urutan (ASC atau DESC). Dalam situasi seperti itu, validasi input atau desain ulang kueri adalah pertahanan yang paling tepat. Untuk nama tabel atau kolom, idealnya nilai tersebut berasal dari kode, dan bukan dari parameter pengguna Namun jika nilai parameter pengguna digunakan untuk menargetkan nama tabel dan nama kolom yang berbeda, maka nilai parameter harus dipetakan ke nama tabel atau kolom yang sah/diharapkan untuk memastikan input pengguna yang tidak divalidasi tidak berakhir dalam kueri. Harap dicatat, ini adalah gejala desain yang buruk dan penulisan ulang penuh harus dipertimbangkan jika waktu memungkinkan Berikut adalah contoh validasi nama tabel
_7 kemudian dapat langsung ditambahkan ke kueri SQL karena sekarang dikenal sebagai salah satu nilai legal dan nilai yang diharapkan untuk nama tabel dalam kueri ini. Perlu diingat bahwa fungsi validasi tabel umum dapat mengakibatkan hilangnya data karena nama tabel digunakan dalam kueri yang tidak diharapkanUntuk sesuatu yang sederhana seperti tata urutan, akan lebih baik jika masukan yang diberikan pengguna diubah menjadi boolean, lalu boolean tersebut digunakan untuk memilih nilai aman untuk ditambahkan ke kueri. Ini adalah kebutuhan yang sangat standar dalam pembuatan kueri dinamis Misalnya
Setiap kali input pengguna dapat dikonversi ke non-String, seperti tanggal, numerik, boolean, jenis enumerasi, dll. sebelum ditambahkan ke kueri, atau digunakan untuk memilih nilai yang akan ditambahkan ke kueri, ini memastikan aman untuk melakukannya Validasi input juga direkomendasikan sebagai pertahanan sekunder dalam SEMUA kasus, bahkan saat menggunakan variabel bind seperti yang akan dibahas nanti di artikel ini. Lebih banyak teknik tentang cara menerapkan validasi input yang kuat dijelaskan dalam Lembar Curang Validasi Input Opsi Pertahanan 4. Keluar dari Semua Input yang Disediakan PenggunaTeknik ini sebaiknya hanya digunakan sebagai upaya terakhir, jika tidak ada cara di atas yang memungkinkan. Validasi input mungkin merupakan pilihan yang lebih baik karena metodologi ini lemah dibandingkan dengan pertahanan lain dan kami tidak dapat menjamin ini akan mencegah semua Injeksi SQL dalam semua situasi Teknik ini untuk menghindari input pengguna sebelum memasukkannya ke dalam kueri. Ini sangat spesifik basis data dalam implementasinya. Biasanya hanya disarankan untuk melakukan retrofit kode lawas saat menerapkan validasi masukan tidak efektif biaya. Aplikasi yang dibuat dari awal, atau aplikasi yang memerlukan toleransi risiko rendah harus dibuat atau ditulis ulang menggunakan kueri berparameter, prosedur tersimpan, atau semacam Object Relational Mapper (ORM) yang membuat kueri Anda untuk Anda Teknik ini bekerja seperti ini. Setiap DBMS mendukung satu atau lebih skema pelolosan karakter khusus untuk jenis kueri tertentu. Jika Anda kemudian keluar dari semua input yang diberikan pengguna menggunakan skema pelolosan yang tepat untuk database yang Anda gunakan, DBMS tidak akan mengacaukan input tersebut dengan kode SQL yang ditulis oleh pengembang, sehingga menghindari kemungkinan kerentanan injeksi SQL. OWASP Enterprise Security API (ESAPI) adalah pustaka kontrol keamanan aplikasi web gratis, sumber terbuka, yang memudahkan pemrogram untuk menulis aplikasi berisiko rendah. Pustaka ESAPI dirancang untuk memudahkan pemrogram memasang kembali keamanan ke dalam aplikasi yang sudah ada. Perpustakaan ESAPI juga berfungsi sebagai dasar yang kuat untuk pengembangan baru
Untuk menemukan javadoc khusus untuk pembuat enkode basis data, klik kelas 8 di sisi kiri. Ada banyak Codec yang diterapkan. Dua codec khusus Database adalah 9, dan 0Cukup klik nama mereka di _1 di bagian atas halaman Interface CodecSaat ini, ESAPI saat ini memiliki pembuat enkode basis data
Pembuat enkode basis data akan segera hadir
Jika encoder basis data Anda hilang, beri tahu kami Detail Pelarian Khusus Basis DataJika Anda ingin membuat rutinitas pelolosan Anda sendiri, berikut detail pelolosan untuk setiap database tempat kami mengembangkan ESAPI Encoder untuk
Oracle Melarikan diriInformasi ini berdasarkan pada Keluar dari Kueri Dinamis¶Untuk menggunakan codec database ESAPI cukup sederhana. Contoh Oracle terlihat seperti
Jadi, jika Anda memiliki kueri Dinamis yang ada yang dihasilkan dalam kode Anda yang akan dikirim ke Oracle yang terlihat seperti ini
Anda akan menulis ulang baris pertama agar terlihat seperti ini _0Dan sekarang akan aman dari injeksi SQL, terlepas dari input yang diberikan Untuk keterbacaan kode maksimum, Anda juga dapat membuat 2 Anda sendiri _1Dengan jenis solusi ini, Anda hanya perlu membungkus setiap parameter yang disediakan pengguna yang diteruskan ke panggilan 3 atau apa pun yang Anda beri nama panggilan itu dan Anda akan selesaiMatikan penggantian karakter¶Gunakan _4 atau 5 untuk memastikan penggantian karakter otomatis dinonaktifkan. Jika penggantian karakter ini diaktifkan, karakter & akan diperlakukan seperti awalan variabel SQLPlus yang memungkinkan penyerang mengambil data pribadiLihat dan di sini untuk informasi lebih lanjut Melarikan diri dari karakter Wildcard di Like Clauses¶Kata kunci _6 memungkinkan pencarian pemindaian teks. Di Oracle, karakter garis bawah _7 hanya cocok dengan satu karakter, sedangkan ampersand 8 digunakan untuk mencocokkan nol atau lebih kemunculan karakter apa pun. Karakter ini harus diloloskan dalam kriteria klausa LIKEMisalnya _2Oracle 10g melarikan diri¶Alternatif untuk Oracle 10g dan yang lebih baru adalah menempatkan 9 dan 0 di sekitar string untuk keluar dari seluruh string. Namun, Anda harus berhati-hati karena belum ada 0 karakter dalam string. Anda harus mencari ini dan jika ada, maka Anda harus menggantinya dengan 2. Jika tidak, karakter tersebut akan mengakhiri pelarian lebih awal, dan dapat menimbulkan kerentananMySQL Melarikan diriMySQL mendukung dua mode pelolosan
5 mode. Cukup enkodekan semua 6 (tanda centang tunggal) karakter dengan 7 (dua tanda centang tunggal) 4 mode, lakukan hal berikut _3Informasi ini didasarkan pada informasi karakter MySQL Escape Pelarian SQL ServerKami belum menerapkan rutinitas pelolosan SQL Server, tetapi yang berikut ini memiliki petunjuk dan tautan yang bagus ke artikel yang menjelaskan cara mencegah serangan injeksi SQL pada server SQL, lihat di sini DB2 Melarikan diriInformasi ini didasarkan pada karakter khusus WebQuery DB2 serta beberapa informasi dari driver JDBC DB2 Oracle Informasi mengenai perbedaan antara beberapa driver DB2 Universal Hex-encoding semua masukanKasus pelolosan yang agak khusus adalah proses hex-encode seluruh string yang diterima dari pengguna (ini dapat dilihat sebagai pelolosan setiap karakter). Aplikasi web harus melakukan hex-encode input pengguna sebelum memasukkannya ke dalam pernyataan SQL. Pernyataan SQL harus mempertimbangkan fakta ini, dan dengan demikian membandingkan datanya Misalnya, jika kita harus mencari catatan yang cocok dengan ID sesi, dan pengguna mengirimkan string abc123 sebagai ID sesi, pernyataan pilih akan menjadi _4 9 harus diganti dengan fasilitas khusus untuk database yang digunakan. String 606162313233 adalah versi hex encoded dari string yang diterima dari pengguna (ini adalah urutan nilai hex dari kode ASCII/UTF-8 dari data pengguna)Jika penyerang mengirimkan string yang berisi karakter kutipan tunggal diikuti dengan upaya mereka untuk menyuntikkan kode SQL, pernyataan SQL yang dibuat hanya akan terlihat seperti _5 0 menjadi kode ASCII (dalam hex) dari kutipan tunggal, yang hanya dikodekan hex seperti karakter lain dalam string. SQL yang dihasilkan hanya dapat berisi angka dan huruf numerik 1 hingga 2, dan tidak pernah ada karakter khusus yang dapat mengaktifkan injeksi SQLMelarikan diri dari SQLi di PHPGunakan pernyataan yang disiapkan dan kueri berparameter. Ini adalah pernyataan SQL yang dikirim ke dan diuraikan oleh server database secara terpisah dari parameter apa pun. Dengan cara ini, penyerang tidak mungkin menyuntikkan SQL berbahaya Anda pada dasarnya memiliki dua opsi untuk mencapai ini
_6
_7PDO adalah opsi universal. Jika Anda terhubung ke database selain MySQL, Anda dapat merujuk ke opsi kedua khusus driver (mis. g. pg_prepare() dan pg_execute() untuk PostgreSQL) Pertahanan TambahanSelain mengadopsi salah satu dari empat pertahanan utama, kami juga merekomendasikan mengadopsi semua pertahanan tambahan ini untuk menyediakan pertahanan secara mendalam. Pertahanan tambahan ini adalah
Hak Istimewa Paling SedikitUntuk meminimalkan potensi kerusakan dari serangan injeksi SQL yang berhasil, Anda harus meminimalkan hak istimewa yang diberikan ke setiap akun database di lingkungan Anda. Jangan tetapkan hak akses jenis DBA atau admin ke akun aplikasi Anda. Kami memahami bahwa ini mudah, dan semuanya hanya "berfungsi" jika Anda melakukannya dengan cara ini, tetapi sangat berbahaya Mulai dari bawah ke atas untuk menentukan hak akses apa yang diperlukan akun aplikasi Anda, daripada mencoba mencari tahu hak akses apa yang perlu Anda ambil. Pastikan bahwa akun yang hanya memerlukan akses baca hanya diberikan akses baca ke tabel yang aksesnya diperlukan Jika akun hanya memerlukan akses ke bagian tabel, pertimbangkan untuk membuat tampilan yang membatasi akses ke bagian data tersebut dan menetapkan akses akun ke tampilan, bukan tabel yang mendasarinya. Jarang, jika pernah, memberikan akses buat atau hapus ke akun basis data Jika Anda menerapkan kebijakan di mana Anda menggunakan prosedur tersimpan di mana saja, dan tidak mengizinkan akun aplikasi untuk secara langsung menjalankan kueri mereka sendiri, maka batasi akun tersebut agar hanya dapat menjalankan prosedur tersimpan yang mereka perlukan. Jangan beri mereka hak apa pun secara langsung ke tabel di database Injeksi SQL bukan satu-satunya ancaman bagi data database Anda. Penyerang dapat dengan mudah mengubah nilai parameter dari salah satu nilai legal yang diberikan kepada mereka, menjadi nilai yang tidak sah bagi mereka, tetapi aplikasi itu sendiri mungkin diizinkan untuk mengakses. Dengan demikian, meminimalkan hak istimewa yang diberikan ke aplikasi Anda akan mengurangi kemungkinan upaya akses tidak sah tersebut, bahkan ketika penyerang tidak mencoba menggunakan injeksi SQL sebagai bagian dari eksploit mereka. Saat Anda melakukannya, Anda harus meminimalkan hak istimewa dari akun sistem operasi yang dijalankan oleh DBMS. Jangan jalankan DBMS Anda sebagai root atau sistem. Sebagian besar DBMS kehabisan kotak dengan akun sistem yang sangat kuat. Misalnya, MySQL berjalan sebagai sistem di Windows secara default. Ubah akun OS DBMS menjadi sesuatu yang lebih sesuai, dengan hak istimewa terbatas Banyak Pengguna DBPerancang aplikasi web harus menghindari penggunaan akun pemilik/admin yang sama di aplikasi web untuk terhubung ke database. Pengguna DB yang berbeda harus digunakan untuk aplikasi web yang berbeda Secara umum, setiap aplikasi web terpisah yang memerlukan akses ke database harus memiliki akun pengguna database yang ditunjuk yang akan digunakan aplikasi untuk terhubung ke DB. Dengan begitu, perancang aplikasi dapat memiliki perincian yang baik dalam kontrol akses, sehingga mengurangi hak istimewa sebanyak mungkin. Setiap pengguna DB kemudian akan memiliki akses pilih ke apa yang dibutuhkannya saja, dan akses tulis sesuai kebutuhan Sebagai contoh, halaman login memerlukan akses baca ke bidang nama pengguna dan sandi tabel, tetapi tidak ada akses tulis dalam bentuk apa pun (tidak boleh menyisipkan, memperbarui, atau menghapus). Namun, halaman pendaftaran tentu membutuhkan hak istimewa untuk dimasukkan ke tabel itu; TampilanAnda dapat menggunakan tampilan SQL untuk lebih meningkatkan perincian akses dengan membatasi akses baca ke bidang tabel tertentu atau gabungan tabel. Ini berpotensi memiliki manfaat tambahan. misalnya, misalkan sistem diperlukan (mungkin karena beberapa persyaratan hukum tertentu) untuk menyimpan kata sandi pengguna, bukan kata sandi yang diasinkan. Perancang dapat menggunakan tampilan untuk mengkompensasi batasan ini; . Setiap serangan injeksi SQL yang berhasil mencuri informasi DB akan dibatasi untuk mencuri hash kata sandi (bahkan bisa berupa hash yang dikunci), karena tidak ada pengguna DB untuk aplikasi web mana pun yang memiliki akses ke tabel itu sendiri Validasi Input daftar yang diizinkanSelain menjadi pertahanan utama saat tidak ada lagi yang memungkinkan (mis. g. , ketika variabel bind tidak legal), validasi input juga bisa menjadi pertahanan sekunder yang digunakan untuk mendeteksi input yang tidak sah sebelum diteruskan ke kueri SQL. Untuk informasi lebih lanjut, silakan lihat Lembar Cheat Validasi Input. Lanjutkan dengan hati-hati di sini. Data yang divalidasi belum tentu aman untuk dimasukkan ke dalam kueri SQL melalui pembuatan string Artikel TerkaitLembar Curang Serangan Injeksi SQL Artikel berikut menjelaskan cara mengeksploitasi berbagai jenis Kerentanan Injeksi SQL pada berbagai platform yang artikel ini dibuat untuk membantu Anda menghindarinya Bagaimana cara membuat database MySQL saya lebih aman?Praktik Terbaik Keamanan MySQL . Hapus Akun Default, Pemetaan Port, dan Pengaturan Lainnya. . Batasi Akses Jarak Jauh. . Berikan Pengguna Hanya Keistimewaan yang Mereka Butuhkan. . Gunakan Akun Non-Root. . Menjaga Server Secara Fisik Aman. . Pastikan Anda Menjaga Audit & Pemantauan yang Tepat. . Nilai Keamanan Basis Data Anda Secara Rutin Bagaimana cara mengamankan koneksi MySQL?MySQL memerlukan sertifikat dan file kunci untuk mengaktifkan sambungan yang aman. . ssl-ca=ca. pem. Mengidentifikasi sertifikat Certificate Authority (CA). ssl-cert=server-cert. pem. Mengidentifikasi sertifikat kunci publik server ssl-key=kunci-server. pem. Mengidentifikasi kunci pribadi server Bagaimana cara mengamankan MySQL Windows?Mengamankan Server MySQL di Windows . Langkah 1. Instal MySQL pada Windows versi terbaru berbasis NT. . Langkah 2. Instal MySQL pada Sistem File NTFS. . Langkah 3. Instal MySQL di Mesin Mandiri. . Langkah 4. Instal MySQL Versi Produksi Terbaru. . Langkah 5. Amankan Akun Pengguna MySQL. . Langkah 6. Nonaktifkan Akses TCP/IP Apa keamanan sistem file di MySQL?1. Keamanan Sistem Operasi. Tugas sistem operasi adalah melindungi instalasi MySQL dan file-filenya dari akses eksternal ilegal . Singkatnya, ini berarti bahwa hanya proses MySQL dan administrator database yang diautentikasi yang dapat menyentuh instalasi MySQL. |