Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Triển khai một hệ thống tham gia có thể định cấu hình, một cách an toàn

Bạn đang làm rất đúng đến mức tôi thực sự cảm thấy có lỗi khi chỉ ra rằng bạn đang làm sai! :)

Bạn chỉ có thể sử dụng các câu lệnh đã chuẩn bị để tham số hóa các giá trị trường — không phải từ định danh SQL như tên cột hoặc bảng. Do đó, bạn sẽ không thể vượt qua A.x , B.z v.v. vào JOIN của bạn tiêu chí bằng các tham số câu lệnh đã chuẩn bị sẵn:bạn phải thay vào đó, hãy làm những gì cảm thấy rất sai và trực tiếp nối chúng vào chuỗi SQL của bạn.

Tuy nhiên, tất cả là không bị mất. Theo một số thứ tự tùy chọn mơ hồ, bạn có thể:

  1. Trình bày cho người dùng một danh sách tùy chọn, từ đó bạn sẽ tập hợp lại 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>
    

    Sau đó, trình xử lý biểu mẫu của bạn:

    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";
    

    Cách tiếp cận này có ưu điểm là, không ảnh hưởng đến PHP (trong trường hợp đó, bạn sẽ có những mối lo ngại lớn hơn nhiều so với SQL injection), SQL tùy ý hoàn toàn không thể tìm đường vào RDBMS của bạn.

  2. Đảm bảo đầu vào của người dùng khớp với một trong các giá trị mong đợi:

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

    Sau đó, trình xử lý biểu mẫu của bạn:

    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]";
    

    Cách tiếp cận này dựa trên in_array của PHP chức năng an toàn (và cũng hiển thị cho người dùng tên cột cơ bản của bạn, nhưng với ứng dụng của bạn, tôi nghi ngờ đó là một mối quan tâm).

  3. Thực hiện một số thao tác làm sạch đầu vào, chẳng hạn như:

    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']) . '`'
    

    Trong khi chúng tôi trích dẫn đầu vào của người dùng ở đây và thay thế bất kỳ nỗ lực nào của người dùng để thoát khỏi trích dẫn đó, cách tiếp cận này có thể chứa đầy đủ các loại lỗi và lỗ hổng bảo mật (trong mb_ereg_replace của PHP chức năng hoặc cách xử lý của MySQL đối với các chuỗi được tạo đặc biệt trong một mã định danh được trích dẫn).

    Nó là xa tốt hơn nếu có thể sử dụng một trong các phương pháp trên để tránh chèn hoàn toàn các chuỗi do người dùng xác định vào SQL của một người.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Làm cách nào để đặt lại các từ dừng trong MYSQL?

  2. Lỗi di chuyển trong django 2; AttributeError:Đối tượng 'str' không có thuộc tính 'giải mã'

  3. Làm cách nào để MySQL Cluster xác định các nút dữ liệu cần tìm kiếm cho một truy vấn SELECT?

  4. MySql SP lồng nhau có thể là một nút cổ chai không?

  5. PDO ::PARAM cho kiểu thập phân?