Memahami SQL-Injection dan Cara Mengatasi Serangan Berbahaya

Apa itu SQL Injection? SQL injection (Injeksi SQL) adalah tindakan jahat (hacker) yang meliputi pencurian, pengubahan penghapusan data dari database seseorang.

Pernyataan SQL untuk dijalankan pada database tanpa sepengetahuan pemilik adalah tindakan Injeksi SQL. Injeksi memiliki banyak cara dalam beroperasi, namun yang simple untuk lebih mudah diserap, saya contohkan injeksi pada input data, seperti username, password atau email dan lain-lain yang tersimpan dalam database.

Beberapa terakhir ini, saya sering mendapat saran ketika posting kode di berbagai forum dengan tema yang sama, yaitu: rekomendasi untuk merubah versi php ke yang baru dengan alasan versi lama beresiko terkena injeksi SQL

Ini jelas harus dipahami dan diterapkan jika kita benar-benar serius dalam mengolah situs menengah keatas/ situs besar. Hal ini dikarenakan hacker lebih suka mencari korban yang telah populer.

Apakah bisa semua situs terkena serangan Injeksi SQL?
Jawabannya NO!!

Injeksi ini mengarah pada database, jadi bagi Anda yang memiliki blog tanpa menggunakan database personal tidak perlu memikirkan hal ini. Saya ambil contoh untuk pengguna dari BLOGSPOT, maka yang akan mengurusi Injeksi adalah Google.

Berikut beberapa tips menghindari Injeksi SQL

Sumber: StackOverflow
Gunakan pernyataan siap dan query parameter. Ini adalah pernyataan SQL yang dikirim ke dan diurai oleh database server secara terpisah dari parameter apapun. cara ini tidak mungkin bisa bagi penyerang untuk menyuntikkan SQL berbahaya.

Pada dasarnya Anda memiliki dua pilihan untuk mencapai hal ini:
  • Menggunakan PDO (untuk setiap driver database yang didukung):
$stmt = $pdo->prepare('SELECT * FROM employees WHERE name = :name');
$stmt->execute(array('name' => $name));
foreach ($stmt as $row) {
    // do something with $row
}
  • Menggunakan MySQL (untuk MySQL):
$stmt = $dbConnection->prepare('SELECT * FROM employees WHERE name = ?');
$stmt->bind_param('s', $name);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
    // do something with $row
}
Jika Anda menghubungkan ke database selain MySQL, ada pilihan kedua driver-spesifik yang dapat Anda lihat (misalnya pg_prepare() dan pg_execute() untuk PostgreSQL). PDO adalah pilihan universal.

Benar menyiapkan sambungan
Perhatikan bahwa bila menggunakan PDO untuk mengakses database MySQL pernyataan nyata disiapkan tidak digunakan secara default. Untuk memperbaiki ini, Anda harus menonaktifkan emulasi dari pernyataan siap. Contoh membuat sambungan menggunakan PDO adalah:
$dbConnection = new PDO('mysql:dbname=dbtest;host=127.0.0.1;charset=utf8', 'user', 'pass');
$dbConnection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
Dalam contoh di atas modus kesalahan tidak benar-benar diperlukan, tetapi disarankan untuk menambahkannya. Cara yang ini, script tidak akan berhenti dengan Kesalahan Fatal ketika sesuatu berjalan salah. Dan memberikan pengembang kesempatan untuk menangkap kesalahan yang dibuang sebagai PDOException (Pengecualian PDO).

Apa yang wajib namun adalah pertama setAttribute() line, yang memberitahu PDO untuk menonaktifkan pernyataan siap ditiru dan menggunakan pernyataan nyata siap. Ini memastikan pernyataan dan nilai-nilai yang tidak diurai oleh PHP sebelum mengirimnya ke server MySQL (memberikan penyerang mungkin ada kesempatan untuk menyuntikkan SQL berbahaya).
Meskipun Anda dapat mengatur charset dalam pilihan dari konstruktor, penting untuk dicatat bahwa 'tua' versi PHP (<5.3.6) diam-diam mengabaikan parameter charset di DSN.

Penjelasan

Apa yang terjadi adalah bahwa pernyataan SQL Anda lulus untuk mempersiapkan parsing dan dikompilasi oleh database server. Dengan menentukan parameter (baik atau parameter bernama seperti:? Nama dalam contoh di atas) Anda memberitahu mesin database di mana Anda ingin menyaring. Kemudian ketika Anda menelepon mengeksekusi, pernyataan siap dikombinasikan dengan nilai parameter yang Anda tentukan.

Yang penting di sini adalah bahwa nilai-nilai parameter yang dikombinasikan dengan pernyataan dikompilasi, bukan string SQL. SQL injection bekerja dengan menipu script ke termasuk string berbahaya ketika menciptakan SQL untuk mengirim ke database.

Jadi dengan mengirimkan SQL sebenarnya terpisah dari parameter, Anda membatasi risiko berakhir dengan sesuatu yang tidak Anda niatkan. Parameter yang Anda kirim bila menggunakan pernyataan yang sudah disiapkan hanya akan diperlakukan sebagai string (meskipun mesin database dapat melakukan beberapa optimasi sehingga parameter mungkin berakhir sebagai nomor juga, tentu saja).

Dalam contoh di atas, jika variabel $name berisi 'Sigit'; DELETE FROM karyawan hasilnya hanya akan menjadi pencarian string " 'Sigit'; DELETE FROM karyawan", dan Anda tidak akan berakhir dengan sebuah meja kosong.

Manfaat lain dengan menggunakan pernyataan siap adalah bahwa jika Anda menjalankan pernyataan yang sama berkali-kali dalam sesi yang sama itu hanya akan diurai dan disusun sekali, memberikan beberapa keuntungan kecepatan.

Berikut contoh (menggunakan PDO):
$preparedStatement = $db->prepare('INSERT INTO table (column) VALUES (:column)');
$preparedStatement->execute(array('column' => $unsafeValue));


Bisakah Laporan Disiapkan Digunakan Untuk Dinamis Query?

Meskipun Anda masih dapat menggunakan pernyataan siap untuk parameter query, struktur query dinamis itu sendiri tidak dapat fitur query parameter tertentu dan tidak dapat diberi parameter.
Untuk skenario tertentu, hal terbaik untuk dilakukan adalah menggunakan filter daftar putih yang membatasi nilai yang mungkin.
URL

Komentar yang bermanfaat mendapat Rating*****oleh Admin blog ini