Php mencegah injeksi sql mysql_real_escape_string

Jika masukan pengguna dimasukkan tanpa modifikasi ke dalam query SQL, maka aplikasi menjadi rentan terhadap injeksi SQL, seperti pada contoh berikut

$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
}
_59

Itu karena pengguna dapat memasukkan sesuatu seperti

$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
}
60, dan kueri menjadi

$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
}
_61

Apa yang dapat dilakukan untuk mencegah hal ini terjadi?


28 Jawaban 28

suara setuju 5105 suara tidak setuju diterima

+50

Gunakan 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

  1. Menggunakan PDO (untuk semua 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
    }
    
  2. Menggunakan MySQLi (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 terhubung ke database selain MySQL, ada opsi kedua khusus driver yang dapat Anda rujuk (mis. g.

$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
}
_62 dan
$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
}
63 untuk PostgreSQL). PDO adalah opsi universal

Menyiapkan koneksi dengan benar

Perhatikan bahwa ketika menggunakan

$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
}
_64 untuk mengakses database MySQL, pernyataan yang sebenarnya disiapkan tidak digunakan secara default. Untuk memperbaikinya, Anda harus menonaktifkan emulasi pernyataan yang disiapkan. Contoh membuat koneksi 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, mode kesalahan tidak sepenuhnya diperlukan, tetapi disarankan untuk menambahkannya. Dengan cara ini skrip tidak akan berhenti dengan a

$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
}
65 ketika terjadi kesalahan. Dan itu memberi pengembang kesempatan untuk
$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
}
_66 kesalahan apa pun yang
$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
}
67n sebagai
$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
}
68s

Namun yang wajib adalah baris

$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
}
_69 pertama, yang memberi tahu PDO untuk menonaktifkan pernyataan siap yang ditiru dan menggunakan pernyataan siap yang nyata. Ini memastikan pernyataan dan nilai tidak diurai oleh PHP sebelum mengirimkannya ke server MySQL (memberikan kemungkinan penyerang tidak memiliki kesempatan untuk menyuntikkan SQL berbahaya)

Meskipun Anda dapat menyetel

$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
}
70 dalam opsi konstruktor, penting untuk dicatat bahwa versi PHP 'lama' (< 5. 3. 6) diam-diam mengabaikan parameter charset di DSN

Penjelasan

Apa yang terjadi adalah pernyataan SQL yang Anda berikan ke

$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
}
71 diuraikan dan dikompilasi oleh server basis data. Dengan menentukan parameter (baik a
$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
}
72 atau parameter bernama seperti
$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
}
73 pada contoh di atas) Anda memberi tahu mesin basis data tempat Anda ingin memfilter. Kemudian ketika Anda memanggil
$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
}
_74, pernyataan yang disiapkan digabungkan dengan nilai parameter yang Anda tentukan

Yang penting di sini adalah nilai parameter digabungkan dengan pernyataan yang dikompilasi, bukan string SQL. Injeksi SQL bekerja dengan mengelabui skrip agar memasukkan string berbahaya saat membuat SQL untuk dikirim ke database. Jadi dengan mengirimkan SQL aktual secara terpisah dari parameter, Anda membatasi risiko berakhir dengan sesuatu yang tidak Anda inginkan. Parameter apa pun yang Anda kirim saat menggunakan pernyataan yang disiapkan hanya akan diperlakukan sebagai string (walaupun mesin basis data dapat melakukan beberapa pengoptimalan sehingga parameter dapat berakhir sebagai angka juga, tentu saja). Dalam contoh di atas, jika

$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
}
_75 variabel mengandung
$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
}
76 hasilnya hanya akan mencari string
$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
}
77, dan Anda tidak akan berakhir dengan meja kosong

Manfaat lain dengan menggunakan pernyataan yang telah disiapkan adalah bahwa jika Anda menjalankan pernyataan yang sama berkali-kali dalam sesi yang sama, itu hanya akan diuraikan dan dikompilasi sekali, memberi Anda beberapa peningkatan kecepatan

Oh, dan karena Anda bertanya tentang cara melakukannya untuk penyisipan, inilah contohnya (menggunakan PDO)

$preparedStatement = $db->prepare('INSERT INTO table (column) VALUES (:column)');

$preparedStatement->execute(array('column' => $unsafeValue));

Bisakah Pernyataan yang Disiapkan Digunakan Untuk Kueri Dinamis?

Meskipun Anda masih dapat menggunakan pernyataan yang telah disiapkan untuk parameter kueri, struktur kueri dinamis itu sendiri tidak dapat diparametrikan dan fitur kueri tertentu tidak dapat diparametrikan

Untuk skenario khusus ini, hal terbaik untuk dilakukan adalah menggunakan filter daftar putih yang membatasi kemungkinan nilai

// Value whitelist
  // $dir can only be 'DESC' or 'ASC'
$dir = !empty($direction) ? 'DESC' : 'ASC'; 

Bagikan

diedit 26 Sep '15 pukul 5. 54

Php mencegah injeksi sql mysql_real_escape_string

Akal Sehat Anda

100k 17 86 155

dijawab 13 Sep '08 jam 12. 30

Php mencegah injeksi sql mysql_real_escape_string
Php mencegah injeksi sql mysql_real_escape_string

suara positif 958 suara negatif

Anda memiliki dua opsi - keluar dari karakter khusus di

$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
}
78 Anda, atau menggunakan kueri berparameter. Keduanya akan melindungi Anda dari injeksi SQL. Kueri berparameter dianggap sebagai praktik yang lebih baik, tetapi karakter yang keluar dari variabel Anda akan membutuhkan lebih sedikit perubahan

Kami akan melakukan string yang lebih sederhana yang keluar terlebih dahulu

//Connect

$unsafe_variable = $_POST["user-input"];
$safe_variable = mysql_real_escape_string($unsafe_variable);

mysql_query("INSERT INTO table (column) VALUES ('" . $safe_variable . "')");

//Disconnect

Lihat juga, detail fungsi

$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
}
_79


Peringatan

Mulai dari PHP5. 5. 0

$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
}
_79 dan ekstensi
$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
}
81 tidak digunakan lagi. Gunakan ekstensi
$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
}
_82 dan fungsi ________0______83 sebagai gantinya


Untuk menggunakan kueri berparameter, Anda perlu menggunakan MySQLi daripada fungsi MySQL. Untuk menulis ulang contoh Anda, kami memerlukan sesuatu seperti berikut ini

<?php
    $mysqli = new mysqli("server", "username", "password", "database_name");

    // TODO - Check that connection was successful.

    $unsafe_variable = $_POST["user-input"];

    $stmt = $mysqli->prepare("INSERT INTO table (column) VALUES (?)");

    // TODO check that $stmt creation succeeded

    // "s" means the database expects a string
    $stmt->bind_param("s", $unsafe_variable);

    $stmt->execute();

    $stmt->close();

    $mysqli->close();
?>

Fungsi kunci yang ingin Anda baca di sana adalah

$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
}
84

Juga, seperti yang disarankan orang lain, Anda mungkin merasa berguna/lebih mudah untuk meningkatkan lapisan abstraksi dengan sesuatu seperti PDO

Harap perhatikan bahwa kasus yang Anda tanyakan cukup sederhana, dan kasus yang lebih kompleks mungkin memerlukan pendekatan yang lebih kompleks. Secara khusus

  • Jika Anda ingin mengubah struktur SQL berdasarkan input pengguna, kueri berparameter tidak akan membantu, dan pelolosan yang diperlukan tidak dicakup oleh
    $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
    }
    
    79. Dalam kasus seperti ini, Anda sebaiknya meneruskan input pengguna melalui daftar putih untuk memastikan hanya nilai 'aman' yang diizinkan masuk
  • Jika Anda menggunakan bilangan bulat dari input pengguna dalam suatu kondisi dan mengambil pendekatan
    $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
    }
    
    79, Anda akan mengalami masalah yang dijelaskan oleh Polinomial dalam komentar di bawah. Kasus ini lebih rumit karena bilangan bulat tidak akan dikelilingi oleh tanda kutip, sehingga Anda dapat menanganinya dengan memvalidasi bahwa masukan pengguna hanya berisi angka.
  • Ada kemungkinan kasus lain yang tidak saya ketahui. Anda mungkin menemukan http. //webappsec. org/proyek/artikel/091007. txt sumber daya yang berguna untuk beberapa masalah halus yang mungkin Anda temui

Bagikan

diedit 31 Mar '14 jam 21. 44

Php mencegah injeksi sql mysql_real_escape_string

Amarnath Balasubramanian

3.822 5 16 40

dijawab 13 Sep '08 pukul 0. 02

Php mencegah injeksi sql mysql_real_escape_string

Akal Sehat Anda

100k 17 86 155

 

 

Artikel yang bagus dan dipikirkan dengan matang. Saya dapat menambahkan bahwa menggunakan filter Sanitize dari PHP adalah semacam (tetapi tidak persis) semacam daftar putih. Misalnya,

$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
}
_93 hanya mengizinkan karakter angka, sehingga karakter daftar putih, bukan seluruh string. Dikombinasikan dengan pernyataan yang disiapkan, itu membuat pendekatan "sabuk dan bretel" yang bagus. –  Sablefoste 20 Jan pukul 17. 12

1  

@Sablefoste Anda tidak memerlukan daftar putih di sini. Sanitasi apa pun akan mubazir. Semakin sedikit aturan yang harus diikuti, semakin sedikit kesalahan yang akan Anda buat. Meskipun Anda dapat melakukan validasi apa pun, lakukan demi logika aplikasi Anda, tetapi bukan untuk basis data. –  Akal Sehat Anda 20 Jan pukul 17. 54

tambahkan komentar .

suara positif 332 suara negatif

Gunakan

$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
}
_64 dan menyiapkan kueri

(

$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
}
95 adalah objek
$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
}
64)

$stmt = $conn->prepare("INSERT INTO tbl VALUES(:id, :name)");
$stmt->bindValue(':id', $id);
$stmt->bindValue(':name', $name);
$stmt->execute();

Bagikan

diedit Sep 11 '15 jam 17. 02

Php mencegah injeksi sql mysql_real_escape_string

Peter Mortensen

9.354 11 66 98

dijawab Okt 3 '12 jam 14. 07

Php mencegah injeksi sql mysql_real_escape_string

Scott Arciszewski

8.793 3 24 71

dijawab 17 Juni 11 pukul 4. 00

Php mencegah injeksi sql mysql_real_escape_string

Scott Arciszewski

8.793 3 24 71

dijawab 13 Sep '08 jam 0. 15

Php mencegah injeksi sql mysql_real_escape_string

Peter Mortensen

9.354 11 66 98

dijawab Jul 3 '11 jam 21. 50

Php mencegah injeksi sql mysql_real_escape_string

Peter Mortensen

9.354 11 66 98

dijawab 3 Juli 12 jam 10. 14

Php mencegah injeksi sql mysql_real_escape_string

Peter Mortensen

9.354 11 66 98

dijawab 23 Jul '12 jam 10. 19

Php mencegah injeksi sql mysql_real_escape_string

Manish Srivastava

9.132 5 54 75

 

 

tambahkan komentar .

suara positif 151 suara negatif

Saya menyukai prosedur tersimpan (MySQL telah memiliki dukungan prosedur tersimpan sejak 5. 0) dari sudut pandang keamanan - kelebihannya adalah -

  1. Sebagian besar basis data (termasuk MySQL) memungkinkan akses pengguna dibatasi untuk menjalankan prosedur tersimpan. Kontrol akses keamanan berbutir halus berguna untuk mencegah eskalasi serangan hak istimewa. Ini mencegah aplikasi yang dikompromikan agar tidak dapat menjalankan SQL secara langsung terhadap database
  2. Mereka mengabstraksi kueri SQL mentah dari aplikasi sehingga lebih sedikit informasi tentang struktur database yang tersedia untuk aplikasi. Ini mempersulit orang untuk memahami struktur yang mendasari database dan merancang serangan yang sesuai
  3. Mereka hanya menerima parameter, jadi ada keuntungan dari kueri berparameter. Tentu saja - IMO Anda masih perlu membersihkan input Anda - terutama jika Anda menggunakan SQL dinamis di dalam prosedur tersimpan

Kerugiannya adalah -

  1. Mereka (prosedur tersimpan) sulit dipelihara dan cenderung berkembang biak dengan sangat cepat. Ini membuat mengelola mereka menjadi masalah
  2. Mereka sangat tidak cocok untuk kueri dinamis - jika dibuat untuk menerima kode dinamis sebagai parameter, maka banyak keuntungan yang ditiadakan

Bagikan

diedit 30 Mei 14 jam 18. 29

Php mencegah injeksi sql mysql_real_escape_string

Peter Mortensen

9.354 11 66 98

dijawab 3 Nov '09 jam 18. 05

Php mencegah injeksi sql mysql_real_escape_string

Peter Mortensen

9.354 11 66 98

dijawab 10 Okt '12 jam 14. 53

Php mencegah injeksi sql mysql_real_escape_string

Peter Mortensen

9.354 11 66 98

dijawab 15 Okt '12 jam 13. 52

Php mencegah injeksi sql mysql_real_escape_string

nbari

1.693 1 8 16

 

 

tambahkan komentar .

suara positif 122 suara negatif

Bagi mereka yang tidak yakin bagaimana menggunakan PDO (berasal dari fungsi

$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
}
87), saya membuat pembungkus PDO yang sangat sederhana yang merupakan satu file. Itu ada untuk menunjukkan betapa mudahnya melakukan semua hal umum yang perlu dilakukan aplikasi. Bekerja dengan PostgreSQL, MySQL, dan SQLite

Pada dasarnya, bacalah saat Anda membaca manual untuk melihat cara menggunakan fungsi PDO dalam kehidupan nyata agar mudah menyimpan dan mengambil nilai dalam format yang Anda inginkan

Saya ingin satu kolom

$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);
_5

Saya ingin hasil array(key => value) (mis. e. untuk membuat kotak pilih)

$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);
_6

Saya ingin hasil baris tunggal

$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);
_7

Saya ingin berbagai hasil

$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);
_8

Bagikan

dijawab Sep 19 '12 jam 18. 10

Php mencegah injeksi sql mysql_real_escape_string

Ram Sharma

6.186 3 15 31

dijawab 3 Agustus '12 jam 19. 59

Php mencegah injeksi sql mysql_real_escape_string

Akal Sehat Anda

100k 17 86 155

dijawab 13 Sep '08 jam 12. 30

Php mencegah injeksi sql mysql_real_escape_string
Php mencegah injeksi sql mysql_real_escape_string

suara positif 958 suara negatif

Anda memiliki dua opsi - keluar dari karakter khusus di

$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
}
78 Anda, atau menggunakan kueri berparameter. Keduanya akan melindungi Anda dari injeksi SQL. Kueri berparameter dianggap sebagai praktik yang lebih baik, tetapi karakter yang keluar dari variabel Anda akan membutuhkan lebih sedikit perubahan

Kami akan melakukan string yang lebih sederhana yang keluar terlebih dahulu

//Connect

$unsafe_variable = $_POST["user-input"];
$safe_variable = mysql_real_escape_string($unsafe_variable);

mysql_query("INSERT INTO table (column) VALUES ('" . $safe_variable . "')");

//Disconnect

Lihat juga, detail fungsi

$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
}
_79


Peringatan

Mulai dari PHP5. 5. 0

$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
}
_79 dan ekstensi
$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
}
81 tidak digunakan lagi. Gunakan ekstensi
$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
}
_82 dan fungsi ________0______83 sebagai gantinya


Untuk menggunakan kueri berparameter, Anda perlu menggunakan MySQLi daripada fungsi MySQL. Untuk menulis ulang contoh Anda, kami memerlukan sesuatu seperti berikut ini

<?php
    $mysqli = new mysqli("server", "username", "password", "database_name");

    // TODO - Check that connection was successful.

    $unsafe_variable = $_POST["user-input"];

    $stmt = $mysqli->prepare("INSERT INTO table (column) VALUES (?)");

    // TODO check that $stmt creation succeeded

    // "s" means the database expects a string
    $stmt->bind_param("s", $unsafe_variable);

    $stmt->execute();

    $stmt->close();

    $mysqli->close();
?>

Fungsi kunci yang ingin Anda baca di sana adalah

$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
}
84

Juga, seperti yang disarankan orang lain, Anda mungkin merasa berguna/lebih mudah untuk meningkatkan lapisan abstraksi dengan sesuatu seperti PDO

Harap perhatikan bahwa kasus yang Anda tanyakan cukup sederhana, dan kasus yang lebih kompleks mungkin memerlukan pendekatan yang lebih kompleks. Secara khusus

  • Jika Anda ingin mengubah struktur SQL berdasarkan input pengguna, kueri berparameter tidak akan membantu, dan pelolosan yang diperlukan tidak dicakup oleh
    $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
    }
    
    79. Dalam kasus seperti ini, Anda sebaiknya meneruskan input pengguna melalui daftar putih untuk memastikan hanya nilai 'aman' yang diizinkan masuk
  • Jika Anda menggunakan bilangan bulat dari input pengguna dalam suatu kondisi dan mengambil pendekatan
    $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
    }
    
    79, Anda akan mengalami masalah yang dijelaskan oleh Polinomial dalam komentar di bawah. Kasus ini lebih rumit karena bilangan bulat tidak akan dikelilingi oleh tanda kutip, sehingga Anda dapat menanganinya dengan memvalidasi bahwa masukan pengguna hanya berisi angka.
  • Ada kemungkinan kasus lain yang tidak saya ketahui. Anda mungkin menemukan http. //webappsec. org/proyek/artikel/091007. txt sumber daya yang berguna untuk beberapa masalah halus yang mungkin Anda temui

Bagikan

diedit 31 Mar '14 jam 21. 44

Php mencegah injeksi sql mysql_real_escape_string

Amarnath Balasubramanian

3.822 5 16 40

dijawab 13 Sep '08 pukul 0. 02

Php mencegah injeksi sql mysql_real_escape_string

Akal Sehat Anda

100k 17 86 155

 

 

Artikel yang bagus dan dipikirkan dengan matang. Saya dapat menambahkan bahwa menggunakan filter Sanitize dari PHP adalah semacam (tetapi tidak persis) semacam daftar putih. Misalnya,

$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
}
_93 hanya mengizinkan karakter angka, sehingga karakter daftar putih, bukan seluruh string. Dikombinasikan dengan pernyataan yang disiapkan, itu membuat pendekatan "sabuk dan bretel" yang bagus. –  Sablefoste 20 Jan pukul 17. 12

1  

@Sablefoste Anda tidak memerlukan daftar putih di sini. Sanitasi apa pun akan mubazir. Semakin sedikit aturan yang harus diikuti, semakin sedikit kesalahan yang akan Anda buat. Meskipun Anda dapat melakukan validasi apa pun, lakukan demi logika aplikasi Anda, tetapi bukan untuk basis data. –  Akal Sehat Anda 20 Jan pukul 17. 54

tambahkan komentar .

suara positif 332 suara negatif

Gunakan

$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
}
_64 dan menyiapkan kueri

(

$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
}
95 adalah objek
$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
}
64)

$stmt = $conn->prepare("INSERT INTO tbl VALUES(:id, :name)");
$stmt->bindValue(':id', $id);
$stmt->bindValue(':name', $name);
$stmt->execute();

Bagikan

diedit Sep 11 '15 jam 17. 02

Php mencegah injeksi sql mysql_real_escape_string

Peter Mortensen

9.354 11 66 98

dijawab Okt 3 '12 jam 14. 07

Php mencegah injeksi sql mysql_real_escape_string

Scott Arciszewski

8.793 3 24 71

dijawab 17 Juni 11 pukul 4. 00

Php mencegah injeksi sql mysql_real_escape_string

Scott Arciszewski

8.793 3 24 71

dijawab 13 Sep '08 jam 0. 15

Php mencegah injeksi sql mysql_real_escape_string

Peter Mortensen

9.354 11 66 98

dijawab Jul 3 '11 jam 21. 50

Php mencegah injeksi sql mysql_real_escape_string

Peter Mortensen

9.354 11 66 98

dijawab 3 Juli 12 jam 10. 14

Php mencegah injeksi sql mysql_real_escape_string

Peter Mortensen

9.354 11 66 98

dijawab 23 Jul '12 jam 10. 19

Php mencegah injeksi sql mysql_real_escape_string

Manish Srivastava

9.132 5 54 75

 

 

tambahkan komentar .

suara positif 151 suara negatif

Saya menyukai prosedur tersimpan (MySQL telah memiliki dukungan prosedur tersimpan sejak 5. 0) dari sudut pandang keamanan - kelebihannya adalah -

  1. Sebagian besar basis data (termasuk MySQL) memungkinkan akses pengguna dibatasi untuk menjalankan prosedur tersimpan. Kontrol akses keamanan berbutir halus berguna untuk mencegah eskalasi serangan hak istimewa. Ini mencegah aplikasi yang dikompromikan agar tidak dapat menjalankan SQL secara langsung terhadap database
  2. Mereka mengabstraksi kueri SQL mentah dari aplikasi sehingga lebih sedikit informasi tentang struktur database yang tersedia untuk aplikasi. Ini mempersulit orang untuk memahami struktur yang mendasari database dan merancang serangan yang sesuai
  3. Mereka hanya menerima parameter, jadi ada keuntungan dari kueri berparameter. Tentu saja - IMO Anda masih perlu membersihkan input Anda - terutama jika Anda menggunakan SQL dinamis di dalam prosedur tersimpan

Kerugiannya adalah -

  1. Mereka (prosedur tersimpan) sulit dipelihara dan cenderung berkembang biak dengan sangat cepat. Ini membuat mengelola mereka menjadi masalah
  2. Mereka sangat tidak cocok untuk kueri dinamis - jika dibuat untuk menerima kode dinamis sebagai parameter, maka banyak keuntungan yang ditiadakan

Bagikan

diedit 30 Mei 14 jam 18. 29

Php mencegah injeksi sql mysql_real_escape_string

Peter Mortensen

9.354 11 66 98

dijawab 3 Nov '09 jam 18. 05

Php mencegah injeksi sql mysql_real_escape_string

Peter Mortensen

9.354 11 66 98

dijawab 10 Okt '12 jam 14. 53

Php mencegah injeksi sql mysql_real_escape_string

Peter Mortensen

9.354 11 66 98

dijawab 15 Okt '12 jam 13. 52

Php mencegah injeksi sql mysql_real_escape_string

nbari

1.693 1 8 16

 

 

tambahkan komentar .

suara positif 122 suara negatif

Bagi mereka yang tidak yakin bagaimana menggunakan PDO (berasal dari fungsi

$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
}
87), saya membuat pembungkus PDO yang sangat sederhana yang merupakan satu file. Itu ada untuk menunjukkan betapa mudahnya melakukan semua hal umum yang perlu dilakukan aplikasi. Bekerja dengan PostgreSQL, MySQL, dan SQLite

Pada dasarnya, bacalah saat Anda membaca manual untuk melihat cara menggunakan fungsi PDO dalam kehidupan nyata agar mudah menyimpan dan mengambil nilai dalam format yang Anda inginkan

Saya ingin satu kolom

$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);
_5

Saya ingin hasil array(key => value) (mis. e. untuk membuat kotak pilih)

$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);
_6

Saya ingin hasil baris tunggal

$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);
_7

Saya ingin berbagai hasil

$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);
_8

Bagikan

dijawab Sep 19 '12 jam 18. 10

Php mencegah injeksi sql mysql_real_escape_string

Ram Sharma

6.186 3 15 31

dijawab 3 Agustus '12 jam 19. 59

Php mencegah injeksi sql mysql_real_escape_string

Akal Sehat Anda

100k 17 86 155

dijawab 13 Sep '08 jam 12. 30

Php mencegah injeksi sql mysql_real_escape_string
Php mencegah injeksi sql mysql_real_escape_string

suara positif 958 suara negatif

Anda memiliki dua opsi - keluar dari karakter khusus di

$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
}
78 Anda, atau menggunakan kueri berparameter. Keduanya akan melindungi Anda dari injeksi SQL. Kueri berparameter dianggap sebagai praktik yang lebih baik, tetapi karakter yang keluar dari variabel Anda akan membutuhkan lebih sedikit perubahan

Kami akan melakukan string yang lebih sederhana yang keluar terlebih dahulu

//Connect

$unsafe_variable = $_POST["user-input"];
$safe_variable = mysql_real_escape_string($unsafe_variable);

mysql_query("INSERT INTO table (column) VALUES ('" . $safe_variable . "')");

//Disconnect

Lihat juga, detail fungsi

$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
}
_79


Peringatan

Mulai dari PHP5. 5. 0

$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
}
_79 dan ekstensi
$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
}
81 tidak digunakan lagi. Gunakan ekstensi
$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
}
_82 dan fungsi ________0______83 sebagai gantinya


Untuk menggunakan kueri berparameter, Anda perlu menggunakan MySQLi daripada fungsi MySQL. Untuk menulis ulang contoh Anda, kami memerlukan sesuatu seperti berikut ini

<?php
    $mysqli = new mysqli("server", "username", "password", "database_name");

    // TODO - Check that connection was successful.

    $unsafe_variable = $_POST["user-input"];

    $stmt = $mysqli->prepare("INSERT INTO table (column) VALUES (?)");

    // TODO check that $stmt creation succeeded

    // "s" means the database expects a string
    $stmt->bind_param("s", $unsafe_variable);

    $stmt->execute();

    $stmt->close();

    $mysqli->close();
?>

Fungsi kunci yang ingin Anda baca di sana adalah

$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
}
84

Juga, seperti yang disarankan orang lain, Anda mungkin merasa berguna/lebih mudah untuk meningkatkan lapisan abstraksi dengan sesuatu seperti PDO

Harap perhatikan bahwa kasus yang Anda tanyakan cukup sederhana, dan kasus yang lebih kompleks mungkin memerlukan pendekatan yang lebih kompleks. Secara khusus

  • Jika Anda ingin mengubah struktur SQL berdasarkan input pengguna, kueri berparameter tidak akan membantu, dan pelolosan yang diperlukan tidak dicakup oleh
    $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
    }
    
    79. Dalam kasus seperti ini, Anda sebaiknya meneruskan input pengguna melalui daftar putih untuk memastikan hanya nilai 'aman' yang diizinkan masuk
  • Jika Anda menggunakan bilangan bulat dari input pengguna dalam suatu kondisi dan mengambil pendekatan
    $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
    }
    
    79, Anda akan mengalami masalah yang dijelaskan oleh Polinomial dalam komentar di bawah. Kasus ini lebih rumit karena bilangan bulat tidak akan dikelilingi oleh tanda kutip, sehingga Anda dapat menanganinya dengan memvalidasi bahwa masukan pengguna hanya berisi angka.
  • Ada kemungkinan kasus lain yang tidak saya ketahui. Anda mungkin menemukan http. //webappsec. org/proyek/artikel/091007. txt sumber daya yang berguna untuk beberapa masalah halus yang mungkin Anda temui

Bagikan

diedit 31 Mar '14 jam 21. 44

Php mencegah injeksi sql mysql_real_escape_string

Amarnath Balasubramanian

3.822 5 16 40

dijawab 13 Sep '08 pukul 0. 02

Php mencegah injeksi sql mysql_real_escape_string

Akal Sehat Anda

100k 17 86 155

 

 

Artikel yang bagus dan dipikirkan dengan matang. Saya dapat menambahkan bahwa menggunakan filter Sanitize dari PHP adalah semacam (tetapi tidak persis) semacam daftar putih. Misalnya,

$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
}
_93 hanya mengizinkan karakter angka, sehingga karakter daftar putih, bukan seluruh string. Dikombinasikan dengan pernyataan yang disiapkan, itu membuat pendekatan "sabuk dan bretel" yang bagus. –  Sablefoste 20 Jan pukul 17. 12

1  

@Sablefoste Anda tidak memerlukan daftar putih di sini. Sanitasi apa pun akan mubazir. Semakin sedikit aturan yang harus diikuti, semakin sedikit kesalahan yang akan Anda buat. Meskipun Anda dapat melakukan validasi apa pun, lakukan demi logika aplikasi Anda, tetapi bukan untuk basis data. –  Akal Sehat Anda 20 Jan pukul 17. 54

tambahkan komentar .

suara positif 332 suara negatif

Gunakan

$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
}
_64 dan menyiapkan kueri

(

$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
}
95 adalah objek
$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
}
64)

$stmt = $conn->prepare("INSERT INTO tbl VALUES(:id, :name)");
$stmt->bindValue(':id', $id);
$stmt->bindValue(':name', $name);
$stmt->execute();

Bagikan

diedit Sep 11 '15 jam 17. 02

Php mencegah injeksi sql mysql_real_escape_string

Peter Mortensen

9.354 11 66 98

dijawab Okt 3 '12 jam 14. 07

Php mencegah injeksi sql mysql_real_escape_string

Scott Arciszewski

8.793 3 24 71

dijawab 17 Juni 11 pukul 4. 00

Php mencegah injeksi sql mysql_real_escape_string

Scott Arciszewski

8.793 3 24 71

dijawab 13 Sep '08 jam 0. 15

Php mencegah injeksi sql mysql_real_escape_string

Peter Mortensen

9.354 11 66 98

dijawab Jul 3 '11 jam 21. 50

Php mencegah injeksi sql mysql_real_escape_string

Peter Mortensen

9.354 11 66 98

dijawab 3 Juli 12 jam 10. 14

Php mencegah injeksi sql mysql_real_escape_string

Peter Mortensen

9.354 11 66 98

dijawab 23 Jul '12 jam 10. 19

Php mencegah injeksi sql mysql_real_escape_string

Manish Srivastava

9.132 5 54 75

 

 

tambahkan komentar .

suara positif 151 suara negatif

Saya menyukai prosedur tersimpan (MySQL telah memiliki dukungan prosedur tersimpan sejak 5. 0) dari sudut pandang keamanan - kelebihannya adalah -

  1. Sebagian besar basis data (termasuk MySQL) memungkinkan akses pengguna dibatasi untuk menjalankan prosedur tersimpan. Kontrol akses keamanan berbutir halus berguna untuk mencegah eskalasi serangan hak istimewa. Ini mencegah aplikasi yang dikompromikan agar tidak dapat menjalankan SQL secara langsung terhadap database
  2. Mereka mengabstraksi kueri SQL mentah dari aplikasi sehingga lebih sedikit informasi tentang struktur database yang tersedia untuk aplikasi. Ini mempersulit orang untuk memahami struktur yang mendasari database dan merancang serangan yang sesuai
  3. Mereka hanya menerima parameter, jadi ada keuntungan dari kueri berparameter. Tentu saja - IMO Anda masih perlu membersihkan input Anda - terutama jika Anda menggunakan SQL dinamis di dalam prosedur tersimpan

Kerugiannya adalah -

  1. Mereka (prosedur tersimpan) sulit dipelihara dan cenderung berkembang biak dengan sangat cepat. Ini membuat mengelola mereka menjadi masalah
  2. Mereka sangat tidak cocok untuk kueri dinamis - jika dibuat untuk menerima kode dinamis sebagai parameter, maka banyak keuntungan yang ditiadakan

Bagikan

diedit 30 Mei 14 jam 18. 29

Php mencegah injeksi sql mysql_real_escape_string

Peter Mortensen

9.354 11 66 98

dijawab 3 Nov '09 jam 18. 05

Php mencegah injeksi sql mysql_real_escape_string

Peter Mortensen

9.354 11 66 98

dijawab 10 Okt '12 jam 14. 53

Php mencegah injeksi sql mysql_real_escape_string

Peter Mortensen

9.354 11 66 98

dijawab 15 Okt '12 jam 13. 52

Php mencegah injeksi sql mysql_real_escape_string

nbari

1.693 1 8 16

 

 

tambahkan komentar .

suara positif 122 suara negatif

Bagi mereka yang tidak yakin bagaimana menggunakan PDO (berasal dari fungsi

$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
}
87), saya membuat pembungkus PDO yang sangat sederhana yang merupakan satu file. Itu ada untuk menunjukkan betapa mudahnya melakukan semua hal umum yang perlu dilakukan aplikasi. Bekerja dengan PostgreSQL, MySQL, dan SQLite

Pada dasarnya, bacalah saat Anda membaca manual untuk melihat cara menggunakan fungsi PDO dalam kehidupan nyata agar mudah menyimpan dan mengambil nilai dalam format yang Anda inginkan

Saya ingin satu kolom

$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);
_5

Saya ingin hasil array(key => value) (mis. e. untuk membuat kotak pilih)

$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);
_6

Saya ingin hasil baris tunggal

$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);
_7

Saya ingin berbagai hasil

$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);
_8

Bagikan

dijawab Sep 19 '12 jam 18. 10

Php mencegah injeksi sql mysql_real_escape_string

Ram Sharma

6.186 3 15 31

dijawab 3 Agustus '12 jam 19. 59

Nicolas Finelli

1.314 1 6 6

 

 

tambahkan komentar .

suara positif 106 suara negatif

Beberapa pedoman untuk keluar dari karakter khusus dalam pernyataan SQL

Jangan gunakan MySQL, ekstensi ini sudah usang, gunakan MySQLi atau PDO

MySQLi

Untuk secara manual keluar dari karakter khusus dalam sebuah string, Anda dapat menggunakan fungsi mysqli_real_escape_string. Fungsi tidak akan berfungsi dengan baik kecuali rangkaian karakter yang benar diatur dengan mysqli_set_charset

Contoh

$preparedStatement = $db->prepare('INSERT INTO table (column) VALUES (:column)');

$preparedStatement->execute(array('column' => $unsafeValue));
_2

Untuk pelolosan otomatis nilai dengan pernyataan yang disiapkan, gunakan mysqli_prepare, dan mysqli_stmt_bind_param di mana tipe untuk variabel ikat yang sesuai harus disediakan untuk konversi yang sesuai

Contoh

$preparedStatement = $db->prepare('INSERT INTO table (column) VALUES (:column)');

$preparedStatement->execute(array('column' => $unsafeValue));
_3

Tidak masalah jika Anda menggunakan pernyataan yang telah disiapkan atau mysqli_real_escape_string, Anda harus selalu mengetahui jenis input data yang Anda gunakan

Jadi jika Anda menggunakan pernyataan yang sudah disiapkan, Anda harus menentukan jenis variabel untuk fungsi mysqli_stmt_bind_param

Dan penggunaan mysqli_real_escape_string adalah untuk, seperti namanya, keluar dari karakter khusus dalam sebuah string, sehingga tidak akan membuat bilangan bulat aman. Tujuan dari fungsi ini adalah untuk mencegah putusnya string dalam pernyataan SQL, dan kerusakan pada database yang dapat ditimbulkannya. mysqli_real_escape_string adalah fungsi yang berguna bila digunakan dengan benar, terutama bila digabungkan dengan sprintf

Contoh

$preparedStatement = $db->prepare('INSERT INTO table (column) VALUES (:column)');

$preparedStatement->execute(array('column' => $unsafeValue));
_4

Bagikan

diedit 16 Juli 14 pukul 2. 47

wiki komunitas


3 putaran, 2 pengguna 88%
Danijel

 

 

tambahkan komentar .

suara positif 101 suara negatif

Saya menggunakan tiga cara berbeda untuk mencegah aplikasi web saya rentan terhadap injeksi SQL

  1. Penggunaan
    $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);
    
    _14, yang merupakan fungsi standar dalam PHP, dan kode ini menambahkan garis miring terbalik ke karakter berikut.
    $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);
    
    _37,
    $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);
    
    38,
    $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);
    
    39,
    $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);
    
    40,
    $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);
    
    31,
    $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);
    
    42 dan
    $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);
    
    43. Lewati nilai input sebagai parameter untuk meminimalkan kemungkinan injeksi SQL
  2. Cara paling canggih adalah menggunakan PDO

Saya harap ini akan membantu Anda

Pertimbangkan kueri berikut

$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);
_44

mysql_real_escape_string() tidak akan melindungi di sini. Jika Anda menggunakan tanda kutip tunggal (' ') di sekitar variabel Anda di dalam kueri Anda, inilah yang melindungi Anda dari hal ini. Berikut adalah solusi di bawah ini untuk ini

$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);
_45

Pertanyaan ini memiliki beberapa jawaban bagus tentang ini

Saya sarankan, menggunakan PDO adalah pilihan terbaik

Sunting

$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);
_14 sudah tidak digunakan lagi sejak PHP 5. 5. 0. Gunakan mysqli atau PDO

Alternatif untuk mysql_real_escape_string() adalah

$preparedStatement = $db->prepare('INSERT INTO table (column) VALUES (:column)');

$preparedStatement->execute(array('column' => $unsafeValue));
_5

Contoh

$preparedStatement = $db->prepare('INSERT INTO table (column) VALUES (:column)');

$preparedStatement->execute(array('column' => $unsafeValue));
_6

Bagikan

diedit 22 Apr '15 jam 12. 13

dijawab 14 Sep '12 jam 14. 37

Soumalya Banerjee

1.422 1 11 22

 

 

tambahkan komentar .

suara positif 92 suara negatif

Mengenai banyak jawaban yang bermanfaat, saya berharap dapat menambahkan beberapa nilai pada utas ini. Injeksi SQL adalah jenis serangan yang dapat dilakukan melalui input pengguna (Input yang diisi oleh pengguna dan kemudian digunakan di dalam kueri), Pola injeksi SQL adalah sintaks kueri yang benar sementara kita dapat menyebutnya. pertanyaan buruk untuk alasan yang buruk, kami berasumsi bahwa mungkin ada orang jahat yang mencoba mendapatkan informasi rahasia (dengan melewati kontrol akses) yang memengaruhi tiga prinsip keamanan (Kerahasiaan, Integritas, Ketersediaan)

Sekarang, poin kami adalah untuk mencegah ancaman keamanan seperti serangan injeksi SQL, pertanyaan yang diajukan (Bagaimana mencegah serangan injeksi SQL menggunakan PHP), lebih realistis, pemfilteran data atau menghapus data input adalah kasus saat menggunakan data input pengguna di dalamnya

Pendekatan saya terhadap injeksi SQL adalah. menghapus data input pengguna sebelum mengirimnya ke database (sebelum menggunakannya di dalam kueri apa pun)

Pemfilteran data untuk (Mengubah data yang tidak aman menjadi data yang aman) Pertimbangkan itu dan MySQLi tidak tersedia, bagaimana Anda bisa mengamankan aplikasi Anda?

  1. Pengguna SQL (membatasi hak istimewa pengguna). operasi SQL yang paling umum adalah (SELECT, UPDATE, INSERT), lalu, mengapa memberikan hak istimewa UPDATE kepada pengguna yang tidak memerlukannya? . login, dan halaman pencarian hanya menggunakan SELECT, lalu mengapa menggunakan pengguna db di halaman ini dengan hak istimewa tinggi?. jangan membuat satu pengguna database untuk semua hak istimewa, untuk semua operasi SQL, Anda dapat membuat skema seperti (deluser, selectuser, updateuser) sebagai nama pengguna agar mudah digunakan

lihat Prinsip hak istimewa terkecil

  1. Penyaringan data. sebelum membuat kueri, input pengguna harus divalidasi dan difilter, untuk pemrogram, penting untuk menentukan beberapa properti untuk setiap variabel input pengguna. tipe data, pola data, dan panjang data. bidang yang berupa angka antara (x dan y) harus divalidasi secara tepat menggunakan aturan eksak, untuk bidang yang berupa string (teks). pola kasusnya, misalnya. nama pengguna harus berisi hanya beberapa karakter katakanlah [a-zA-Z0-9_-. ] panjangnya bervariasi antara (x dan n) di mana x dan n (bilangan bulat, x <=n ). Aturan. membuat filter yang tepat dan aturan validasi adalah praktik terbaik untuk saya

  2. Gunakan alat lain. Di sini, saya juga akan setuju dengan Anda bahwa pernyataan yang disiapkan (kueri parametrik) dan prosedur Tersimpan, kerugiannya di sini adalah cara-cara ini membutuhkan keterampilan tingkat lanjut yang tidak ada di sebagian besar pengguna, ide dasarnya di sini adalah untuk membedakan antara kueri SQL dan data yang . untuk informasi lebih lanjut silahkan baca OWASP SQL Injection Prevention Cheat Sheet

Sekarang, jika Anda adalah pengguna tingkat lanjut, mulailah menggunakan pertahanan ini sesuka Anda, tetapi, untuk pemula, jika mereka tidak dapat dengan cepat menerapkan prosedur tersimpan dan pernyataan yang disiapkan, lebih baik memfilter input data sebanyak yang mereka bisa.

Akhirnya, anggap saja pengguna mengirimkan teks ini di bawah alih-alih memasukkan nama penggunanya

$preparedStatement = $db->prepare('INSERT INTO table (column) VALUES (:column)');

$preparedStatement->execute(array('column' => $unsafeValue));
_7

Input ini dapat diperiksa lebih awal tanpa pernyataan yang disiapkan dan prosedur tersimpan, tetapi untuk amannya, menggunakannya dimulai setelah pemfilteran dan validasi data pengguna

Poin terakhir adalah mendeteksi perilaku tak terduga yang membutuhkan lebih banyak usaha dan kerumitan, tidak disarankan untuk aplikasi web biasa. Perilaku tak terduga pada masukan pengguna di atas adalah. SELECT, UNION, IF, SUBSTRING, BENCHMARK, SHA, root setelah kata-kata ini terdeteksi, Anda dapat menghindari input

UPDATE1

Seorang pengguna berkomentar bahwa posting ini tidak berguna, oke. Inilah yang disediakan

Pertahanan primer

Pilihan 1. Penggunaan Pernyataan yang Disiapkan (Kueri Parameter)
Pilihan 2. Penggunaan Prosedur Tersimpan
Opsi #3. Melarikan diri dari semua Input yang Disediakan Pengguna

Pertahanan tambahan

Juga Menegakkan. Hak Istimewa Paling Sedikit
Juga Lakukan. Validasi Input Daftar Putih

Seperti yang Anda ketahui, mengklaim artikel apa pun harus didukung oleh argumen yang valid, setidaknya satu referensi. Kalau tidak, itu dianggap sebagai serangan dan klaim buruk

Pembaruan2

Dari manual PHP, PHP. Laporan yang Disiapkan - Manual

Melarikan diri dan injeksi SQL

Variabel terikat akan diloloskan secara otomatis oleh server. Server menyisipkan nilai yang diloloskan pada tempat yang sesuai ke dalam templat pernyataan sebelum dieksekusi. Petunjuk harus diberikan ke server untuk jenis variabel terikat, untuk membuat konversi yang sesuai. Lihat fungsi mysqli_stmt_bind_param() untuk informasi selengkapnya

Pelarian nilai secara otomatis di dalam server terkadang dianggap sebagai fitur keamanan untuk mencegah injeksi SQL. Tingkat keamanan yang sama dapat dicapai dengan pernyataan yang tidak disiapkan, jika nilai masukan lolos dengan benar

Pembaruan3

Saya membuat kasus uji untuk mengetahui bagaimana PDO dan MySQLi mengirimkan kueri ke server MySQL saat menggunakan pernyataan yang disiapkan

PDO

$preparedStatement = $db->prepare('INSERT INTO table (column) VALUES (:column)');

$preparedStatement->execute(array('column' => $unsafeValue));
_8

Log Kueri

$preparedStatement = $db->prepare('INSERT INTO table (column) VALUES (:column)');

$preparedStatement->execute(array('column' => $unsafeValue));
_9

MySQLi

// Value whitelist
  // $dir can only be 'DESC' or 'ASC'
$dir = !empty($direction) ? 'DESC' : 'ASC'; 
0

Log Kueri

// Value whitelist
  // $dir can only be 'DESC' or 'ASC'
$dir = !empty($direction) ? 'DESC' : 'ASC'; 
_1

Jelas bahwa pernyataan yang disiapkan juga lolos dari data, tidak ada yang lain

Seperti juga disebutkan dalam pernyataan di atas

$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);
_47, oleh karena itu, ini membuktikan bahwa validasi data seperti
$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);
48 adalah ide yang baik untuk nilai integer sebelum mengirim kueri apa pun, selain itu, mencegah data pengguna yang berbahaya sebelum mengirim kueri adalah pendekatan yang benar dan valid

Silakan lihat pertanyaan ini untuk detail lebih lanjut. PDO mengirimkan kueri mentah ke MySQL sementara MySQLi mengirimkan kueri yang sudah disiapkan, keduanya menghasilkan hasil yang sama

Referensi

  1. Injeksi SQL
  2. Informasi keamanan
  3. Prinsip Keamanan
  4. Validasi data

Bagikan

diedit Mar 24 '14 jam 21. 05

wiki komunitas


11 putaran, 4 pengguna 73%
pengguna1646111

 

 

tambahkan komentar .

suara positif 89 suara negatif

Alternatif sederhana untuk masalah ini dapat diselesaikan dengan memberikan izin yang sesuai di database itu sendiri. Sebagai contoh. jika Anda menggunakan database mysql. kemudian masuk ke database melalui terminal atau ui yang disediakan dan ikuti saja perintah ini

// Value whitelist
  // $dir can only be 'DESC' or 'ASC'
$dir = !empty($direction) ? 'DESC' : 'ASC'; 
_2

Ini akan membatasi pengguna untuk hanya dibatasi dengan kueri yang ditentukan saja. Hapus izin hapus sehingga data tidak akan pernah dihapus dari kueri yang dipecat dari halaman php. Hal kedua yang harus dilakukan adalah menghapus hak istimewa sehingga mysql menyegarkan izin dan pembaruan

// Value whitelist
  // $dir can only be 'DESC' or 'ASC'
$dir = !empty($direction) ? 'DESC' : 'ASC'; 
_3

informasi lebih lanjut tentang siram

Untuk melihat hak istimewa pengguna saat ini, aktifkan kueri berikut

// Value whitelist
  // $dir can only be 'DESC' or 'ASC'
$dir = !empty($direction) ? 'DESC' : 'ASC'; 
_4

Belajar lebih tentang

Bagikan

diedit 23 Juli 14 jam 9. 17

dijawab 25 Okt '12 jam 8. 07

apurv nerlekar

1.236 10 17

 

 

tambahkan komentar .

suara positif 77 suara negatif

Cara sederhana adalah dengan menggunakan kerangka kerja PHP seperti atau Laravel yang memiliki fitur bawaan seperti pemfilteran dan rekaman aktif, sehingga Anda tidak perlu khawatir dengan nuansa ini.

Bagikan

diedit 16 Juli 14 pukul 2. 48

wiki komunitas


2 putaran, 2 pengguna 60%
Peter Mortensen

 

 

tambahkan komentar .

suara positif 70 suara negatif

Peringatan. pendekatan yang dijelaskan dalam jawaban ini hanya berlaku untuk skenario yang sangat spesifik dan tidak aman karena serangan injeksi SQL tidak hanya mengandalkan kemampuan menyuntik

$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);
49

Jika penyerang mencoba meretas dengan formulir melalui variabel

$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);
50 PHP atau dengan string kueri URL, Anda dapat menangkapnya jika tidak aman

// Value whitelist
  // $dir can only be 'DESC' or 'ASC'
$dir = !empty($direction) ? 'DESC' : 'ASC'; 
_5

Karena

$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);
_51,
$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);
52,
$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);
53,
$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);
54,
$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);
55, dll. adalah pertanyaan umum untuk database SQL penyerang. Mungkin juga digunakan oleh banyak aplikasi peretasan

Tetapi Anda harus berhati-hati, bahwa Anda tidak boleh menulis ulang kueri aman dari situs Anda. Kode di atas memberi Anda tip, untuk menulis ulang atau mengarahkan ulang (itu tergantung pada Anda) string kueri dinamis khusus peretasan itu ke halaman yang akan menyimpan alamat IP penyerang, atau BAHKAN COOKIES MEREKA, riwayat, browser, atau lainnya

Bagikan

diedit 20 Jan '15 pukul 7. 33

wiki komunitas


5 putaran, 3 pengguna 61%
Pelayan

 

 

tambahkan komentar .

suara positif 64 suara negatif

Ada begitu banyak jawaban untuk PHP dan MySQL, tetapi di sini ada kode untuk PHP dan Oracle untuk mencegah injeksi SQL serta penggunaan rutin driver oci8

// Value whitelist
  // $dir can only be 'DESC' or 'ASC'
$dir = !empty($direction) ? 'DESC' : 'ASC'; 
_6

Bagikan

diedit 16 Juli 14 pukul 2. 53

wiki komunitas


3 putaran, 3 pengguna 69%
Chintan Gor

 

 

tambahkan komentar .

suara positif 59 suara negatif

Menggunakan PDO dan MYSQLi adalah praktik yang baik untuk mencegah injeksi SQL, tetapi jika Anda benar-benar ingin bekerja dengan fungsi dan kueri MySQL, akan lebih baik menggunakan

mysql_real_escape_string

// Value whitelist
  // $dir can only be 'DESC' or 'ASC'
$dir = !empty($direction) ? 'DESC' : 'ASC'; 
_7

Ada lebih banyak kemampuan untuk mencegah hal ini. seperti identifikasi - jika inputnya adalah string, angka, karakter atau larik, ada begitu banyak fungsi bawaan untuk mendeteksi ini. Juga akan lebih baik menggunakan fungsi-fungsi ini untuk memeriksa data masukan

is_string

// Value whitelist
  // $dir can only be 'DESC' or 'ASC'
$dir = !empty($direction) ? 'DESC' : 'ASC'; 
_8

is_numeric

// Value whitelist
  // $dir can only be 'DESC' or 'ASC'
$dir = !empty($direction) ? 'DESC' : 'ASC'; 
_9

Dan jauh lebih baik menggunakan fungsi tersebut untuk memeriksa data masukan dengan

$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
}
79

Bagikan

diedit 16 Juli 14 pukul 2. 51

wiki komunitas


2 putaran, 2 pengguna 87%
Rakesh Sharma

 

5  

Selain itu, sama sekali tidak ada gunanya memeriksa anggota array $_POST dengan is_string() –  Akal Sehat Anda 18 Jan '14 pukul 7. 06

9  

PERINGATAN.

$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);
_14 tidak sempurna. –  eggyal 25 Apr '14 jam 14. 54

1  

@YourCommonSense yang harus Anda yakini jadi apa yang ingin Anda perbarui –  Rakesh Sharma 8 Mei '14 pukul 8. 38

3  

$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
}
79 sekarang sudah tidak digunakan lagi, jadi ini bukan lagi opsi yang layak. Ini akan dihapus dari PHP di masa mendatang. Yang terbaik adalah beralih ke apa yang direkomendasikan oleh orang-orang PHP atau MySQL. –  jww Apr 8 '15 jam 6. 53

tambahkan komentar .

suara positif 37 suara negatif

Ide yang bagus adalah menggunakan 'peta objek-relasional' seperti Idiorm

//Connect

$unsafe_variable = $_POST["user-input"];
$safe_variable = mysql_real_escape_string($unsafe_variable);

mysql_query("INSERT INTO table (column) VALUES ('" . $safe_variable . "')");

//Disconnect
_0

Ini tidak hanya menyelamatkan Anda dari injeksi SQL, tetapi juga dari kesalahan sintaksis

Bagikan

diedit 24 Maret 14 jam 20. 56

wiki komunitas


2 putaran, 2 pengguna 96%
Thomas Ahle

 

 

tambahkan komentar .

suara positif 31 suara negatif

Saya telah menulis fungsi kecil ini beberapa tahun yang lalu

//Connect

$unsafe_variable = $_POST["user-input"];
$safe_variable = mysql_real_escape_string($unsafe_variable);

mysql_query("INSERT INTO table (column) VALUES ('" . $safe_variable . "')");

//Disconnect
_1

Ini memungkinkan menjalankan pernyataan dalam String C#-ish one-liner. Memformat seperti

//Connect

$unsafe_variable = $_POST["user-input"];
$safe_variable = mysql_real_escape_string($unsafe_variable);

mysql_query("INSERT INTO table (column) VALUES ('" . $safe_variable . "')");

//Disconnect
_2

Itu lolos mengingat tipe variabel. Jika Anda mencoba membuat parameter tabel, nama kolom, itu akan gagal karena menempatkan setiap string dalam tanda kutip yang merupakan sintaks yang tidak valid

PEMBARUAN KEAMANAN. Versi

$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);
_59 sebelumnya mengizinkan injeksi dengan menambahkan {#} token ke dalam data pengguna. Versi
$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);
60 ini tidak menimbulkan masalah jika penggantinya berisi token ini

Apakah mysql_real_escape_string mencegah injeksi SQL?

PHP menyediakan mysql_real_escape_string() untuk melepaskan karakter khusus dalam sebuah string sebelum mengirim kueri ke MySQL. Fungsi ini diadopsi oleh banyak orang untuk menghindari tanda kutip tunggal dalam string dan pada kesempatan yang sama mencegah serangan injeksi SQL .

Apakah mysql_real_escape_string aman?

Jika Anda menggunakan mysql_real_escape_string secara konsisten setiap kali Anda memasukkan konten ke dalam literal string SQL, tidak apa-apa, tidak ada masalah keamanan .

Apakah mysql_real_escape_string sudah usang?

Ekstensi ini tidak digunakan lagi di PHP 5. 5. 0, dan dihapus di PHP 7. 0 .

Apa gunanya fungsi mysql_real_escape_string ()?

Fungsi real_escape_string() / mysqli_real_escape_string() mengeluarkan karakter khusus dalam string untuk digunakan dalam kueri SQL, dengan mempertimbangkan rangkaian karakter koneksi saat ini.