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

Menerapkan sistem penyambungan yang dapat dikonfigurasi, dengan aman

Anda melakukan banyak hal dengan benar sehingga saya benar-benar merasa bersalah menunjukkan bahwa Anda melakukan sesuatu yang salah! :)

Anda hanya dapat menggunakan pernyataan yang disiapkan untuk membuat parameter nilai bidang—bukan pengidentifikasi SQL seperti nama kolom atau tabel. Oleh karena itu, Anda tidak akan dapat melewati A.x , B.z dll. ke dalam JOIN kriteria melalui parameter pernyataan yang disiapkan:Anda harus alih-alih lakukan apa yang terasa sangat salah dan langsung gabungkan ke dalam string SQL Anda.

Namun, semua tidak hilang. Dalam beberapa urutan preferensi yang tidak jelas, Anda dapat:

  1. Sajikan pengguna dengan daftar opsi, dari mana Anda kemudian menyusun kembali SQL:

    <select name="join_a">
      <option value="1">x</option>
      <option value="2">y</option>
    </select>
    <select name="join_b">
      <option value="1">z</option>
      <option value="2">y</option>
    </select>
    

    Kemudian penangan formulir Anda:

    switch ($_POST['join_a']) {
      case 1:  $acol = 'x'; break;
      case 2:  $acol = 'y'; break;
      default: die('Invalid input');
    }
    switch ($_POST['join_b']) {
      case 1:  $bcol = 'z'; break;
      case 2:  $bcol = 'y'; break;
      default: die('Invalid input');
    }
    
    $sql .= "FROM A JOIN B ON A.$acol = B.$bcol";
    

    Pendekatan ini memiliki keuntungan bahwa, selain mengorbankan PHP (dalam hal ini Anda akan memiliki masalah yang jauh lebih besar daripada injeksi SQL), SQL arbitrer sama sekali tidak bisa temukan jalannya ke RDBMS Anda.

  2. Pastikan input pengguna cocok dengan salah satu nilai yang diharapkan:

    <select name="join_a">
      <option>x</option>
      <option>y</option>
    </select>
    <select name="join_b">
      <option>z</option>
      <option>y</option>
    </select>
    

    Kemudian penangan formulir Anda:

    if (!in_array($_POST['join_a'], ['x', 'y'])
     or !in_array($_POST['join_b'], ['z', 'y']))
       die('Invalid input');
    
    $sql .= "FROM A JOIN B ON A.$_POST[join_a] = B.$_POST[join_b]";
    

    Pendekatan ini bergantung pada in_array PHP berfungsi untuk keamanan (dan juga memperlihatkan kepada pengguna nama kolom dasar Anda, tetapi mengingat aplikasi Anda, saya ragu itu menjadi perhatian).

  3. Lakukan beberapa pembersihan input, seperti:

    mb_regex_encoding($charset); // charset of database connection
    $sql .= 'FROM A JOIN B ON A.`' . mb_ereg_replace('`', '``', $_POST['join_a']) . '`'
                        . ' = B.`' . mb_ereg_replace('`', '``', $_POST['join_b']) . '`'
    

    Sementara kami di sini mengutip input pengguna dan mengganti upaya apa pun oleh pengguna untuk melarikan diri dari kutipan itu, pendekatan ini bisa penuh dengan segala macam kekurangan dan kerentanan (baik dalam mb_ereg_replace PHP fungsi atau penanganan MySQL terhadap string yang dibuat khusus dalam pengenal yang dikutip).

    Itu jauh lebih baik jika memungkinkan untuk menggunakan salah satu metode di atas untuk menghindari penyisipan string yang ditentukan pengguna ke dalam SQL seseorang sama sekali.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. perbarui baris tanpa menghapus nilai sebelumnya di mysql

  2. MySQL - berapa lama membuat indeks?

  3. Pengunggahan gambar PHP tot MySQL tidak berfungsi

  4. Bagaimana cara menyimpan informasi db connect yang aman?

  5. Memisahkan nilai mysql menjadi beberapa bagian yang tidak diketahui