Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Mengganti fungsi mysql_* dengan PDO dan pernyataan yang disiapkan

Terima kasih atas pertanyaan yang menarik. Ini dia:

Itu lolos dari karakter berbahaya,

Konsep Anda benar-benar salah.
Sebenarnya "karakter berbahaya" adalah mitos, tidak ada. Dan mysql_real_escape_string melarikan diri tetapi hanya pembatas string . Dari definisi ini Anda dapat menyimpulkan batasannya - ini hanya berfungsi untuk string .

namun, itu masih rentan terhadap serangan lain yang dapat berisi karakter aman tetapi mungkin berbahaya untuk menampilkan data atau dalam beberapa kasus, memodifikasi atau menghapus data dengan jahat.

Anda mencampur semuanya di sini.
Berbicara tentang database,

  • untuk senarnya TIDAK rentan. Selama string Anda dikutip dan diloloskan, mereka tidak bisa "ubah atau hapus data dengan jahat".*
  • untuk tipe data lainnya - ya, tidak berguna . Tapi bukan karena agak "tidak aman" melainkan hanya karena penggunaan yang tidak tepat.

Adapun data yang ditampilkan, saya kira itu di luar topik dalam pertanyaan terkait PDO, karena PDO juga tidak ada hubungannya dengan menampilkan data.

keluar dari input pengguna

^^^ Khayalan lain yang perlu diperhatikan!

  • masukan pengguna sama sekali tidak ada hubungannya dengan meloloskan diri . Seperti yang dapat Anda pelajari dari definisi sebelumnya, Anda harus keluar dari string, bukan "input pengguna" apa pun. Jadi, sekali lagi:

    • Anda memiliki escape string, apa pun sumbernya
    • tidak ada gunanya menghindari jenis data lain, apa pun sumbernya.

Mengerti?
Sekarang, saya harap Anda memahami batasan melarikan diri serta kesalahpahaman "karakter berbahaya".

Menurut pemahaman saya, menggunakan PDO/pernyataan yang disiapkan jauh lebih aman

Tidak juga.
Faktanya, ada empat bagian kueri berbeda yang dapat kita tambahkan ke dalamnya secara dinamis:

  • sebuah string
  • angka
  • pengidentifikasi
  • kata kunci sintaks.

jadi, Anda dapat melihat bahwa melarikan diri hanya mencakup satu masalah. (tetapi tentu saja, jika Anda memperlakukan angka sebagai string (menempatkannya dalam tanda kutip), bila berlaku , Anda juga dapat membuatnya aman)

sementara pernyataan yang disiapkan mencakup - ugh - seluruh 2 masalah! Masalah besar;-)

Untuk 2 masalah lainnya, lihat jawaban saya sebelumnya, Dalam PHP saat mengirimkan string ke database, haruskah saya menangani karakter ilegal menggunakan htmlspecialchars() atau menggunakan ekspresi reguler?

Sekarang, nama fungsi berbeda sehingga mysql_query, mysql_fetch_array, mysql_num_rows dll tidak lagi berfungsi.

Itu adalah delusi serius lainnya dari pengguna PHP , bencana alam, bencana:

Bahkan saat menggunakan driver mysql lama, seseorang tidak boleh menggunakan fungsi API kosong dalam kode mereka! Seseorang harus meletakkannya di beberapa fungsi perpustakaan untuk penggunaan sehari-hari! (Bukan sebagai ritual ajaib, tetapi hanya untuk membuat kode lebih pendek, tidak berulang, tahan kesalahan, lebih konsisten, dan mudah dibaca).

Hal yang sama juga berlaku untuk PDO!

Sekarang lanjutkan dengan pertanyaan Anda lagi.

tetapi dengan menggunakannya, apakah ini menghilangkan kebutuhan untuk menggunakan sesuatu seperti mysql_real_escape_string?

YA.

Tapi saya pikir ini kira-kira ide tentang apa yang harus dilakukan untuk mengambil pengguna dari database

Bukan untuk mengambil, tetapi untuk menambahkan data apa pun ke kueri !

Anda harus memberikan panjang setelah PDO:PARAM_STR jika saya tidak salah

Anda bisa, tetapi Anda tidak harus melakukannya.

Sekarang, apakah ini semua aman?

Dalam hal keamanan basis data, tidak ada titik lemah dalam kode ini. Tidak ada yang perlu diamankan di sini.

untuk keamanan tampilan - cukup telusuri situs ini untuk XSS kata kunci.

Semoga saya menjelaskan masalah ini.

BTW, untuk sisipan panjang Anda dapat menggunakan beberapa fungsi yang saya tulis suatu hari nanti, Sisipkan/perbarui fungsi pembantu menggunakan PDO

Namun, saya tidak menggunakan pernyataan yang disiapkan saat ini, karena saya lebih memilih placeholder buatan sendiri daripada mereka, menggunakan perpustakaan saya sebutkan di atas. Jadi, untuk melawan kode yang diposting oleh riha di bawah ini, itu akan sesingkat 2 baris ini:

$sql  = 'SELECT * FROM `users` WHERE `name`=?s AND `type`=?s AND `active`=?i';
$data = $db->getRow($sql,$_GET['name'],'admin',1);

Tetapi tentu saja Anda dapat memiliki kode yang sama menggunakan pernyataan yang disiapkan juga.

* (yes I am aware of the Schiflett's scaring tales)



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. GROUP BY perilaku ketika tidak ada fungsi agregat hadir dalam klausa SELECT

  2. Koneksi jarak jauh MySQL gagal dengan metode otentikasi yang tidak diketahui

  3. Cara Mendapatkan Hari Terakhir Bulan Ini di MySQL

  4. Bagaimana saya bisa menghitung jumlah baris yang dikembalikan oleh kueri MySQL?

  5. Bagaimana mengkonversi IPv6 dari biner untuk penyimpanan di MySQL