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

Chuyển sang các câu lệnh soạn sẵn

Tôi đã từng ở trong tình huống tương tự. Tôi cũng đang sử dụng các câu lệnh nối, sau đó tôi chuyển đơn đăng ký của mình sang các câu lệnh đã chuẩn bị.

tin xấu là bạn sẽ thay đổi mọi câu lệnh SQL được xây dựng bằng cách nối dữ liệu máy khách với câu lệnh SQL, hầu như sẽ là mọi câu lệnh SQL mà bạn có trong 50 tệp nguồn của mình.

tin tốt lành lợi ích từ việc chuyển sang các báo cáo đã chuẩn bị là vô giá, ví dụ:

1-bạn sẽ không bao giờ lo lắng về thứ gọi là "cuộc tấn công SQL Injection"

php hướng dẫn sử dụng nói

Đối với tôi, lý do đó - trí tuệ - là đủ để trả chi phí thay đổi mã nguồn của tôi. , bây giờ khách hàng của bạn có thể nhập vào trường tên biểu mẫu robert; DROP table students; -- ;) và bạn cảm thấy an toàn rằng sẽ không có chuyện gì xảy ra

2- bạn không cần phải thoát khỏi các tham số máy khách nữa. bạn có thể trực tiếp sử dụng chúng trong câu lệnh SQL, chẳng hạn như:

$query = "SELECT FROM user WHERE id = ?";
$vars[] = $_POST['id'];

thay vì

$id = $mysqli->real_escape_string($_POST['id']);
$query = "SELECT FROM user WHERE id = $id";

đó là điều bạn phải làm trước khi sử dụng các câu lệnh đã chuẩn bị sẵn, điều này khiến bạn có nguy cơ quên thoát khỏi một tham số như một con người bình thường. và tất cả những gì cần thiết để kẻ tấn công làm hỏng hệ thống của bạn chỉ là 1 tham số không thoát.

Thay đổi mã

Thông thường, việc thay đổi các tệp nguồn luôn tiềm ẩn rủi ro và khó khăn, đặc biệt nếu thiết kế phần mềm của bạn tồi và nếu bạn không có kế hoạch kiểm tra rõ ràng. nhưng tôi sẽ cho bạn biết những gì tôi đã làm để làm cho nó dễ dàng nhất có thể.

Tôi đã tạo một hàm mà mọi mã tương tác cơ sở dữ liệu sẽ sử dụng, vì vậy bạn có thể thay đổi những gì bạn muốn sau này ở một nơi - hàm đó- bạn có thể tạo một cái gì đó như thế này

class SystemModel
{
    /**
     * @param string $query
     * @param string $types
     * @param array $vars
     * @param \mysqli $conn
     * @return boolean|$stmt
     */
    public function preparedQuery($query,$types, array $vars, $conn)
    {
        if (count($vars) > 0) {
            $hasVars = true;
        }
        array_unshift($vars, $types);
        $stmt = $conn->prepare($query);
        if (! $stmt) {
            return false;
        }
        if (isset($hasVars)) {
            if (! call_user_func_array(array( $stmt, 'bind_param'), $this->refValues($vars))) {
                return false;
            }
        }
        $stmt->execute();
        return $stmt;
    }

    /* used only inside preparedQuery */
    /* code taken from: https://stackoverflow.com/a/13572647/5407848 */
    protected function refValues($arr)
    {
        if (strnatcmp(phpversion(), '5.3') >= 0) {
            $refs = array();
            foreach ($arr as $key => $value)
                $refs[$key] = &$arr[$key];
                return $refs;
        }
        return $arr;
    }
}

Bây giờ, bạn có thể sử dụng giao diện này ở bất kỳ đâu bạn muốn trong các tệp nguồn của mình, ví dụ:hãy thay đổi các câu lệnh SQL hiện tại mà bạn đã cung cấp trong câu hỏi. Hãy để chúng tôi thay đổi điều này

$mysqli = new mysqli('localhost', "root", "", "testdb");
$addresult = "
                SELECT a.firstnames, a.surname, a.schoolrole, a.datejoined 
                FROM teachers a LEFT JOIN schools b ON a.schoolid = b.id 
                WHERE b.id = '".$inputvalues['schoolid']."'";

if( $result = $mysqli->query($addresult) ) {
    while($row = $result->fetch_all())
    {
        $returnResult = $row;
    }
}

Vào cái này

$mysqli = new mysqli('localhost', "root", "", "testdb");
$sysModel = new SystemModel();
$addresult = "
                SELECT a.firstnames, a.surname, a.schoolrole, a.datejoined
                FROM teachers a LEFT JOIN schools b ON a.schoolid = b.id
                WHERE b.id = ?";
$types = "i"; // for more information on paramters types, please check :
//https://php.net/manual/en/mysqli-stmt.bind-param.php
$vars = [];
$vars[] = $inputvalues['schoolid'];

$stmt = $sysModel->preparedQuery($addresult, $types, $vars, $mysqli);
if (!$stmt || $stmt->errno) {
   die('error'); // TODO: change later for a better illustrative output
}
$result = $stmt->get_result();
$returnResult = [];
while ($row = $result->fetch_array(MYSQLI_ASSOC)) {
    $returnResult[] = $row;
}

Có, cuộc tấn công Sql Injection được áp dụng bằng cách nối chuỗi xấu vào câu lệnh SQL của bạn. cho dù nó là INSERT , SELECT , DELETE , UPDATE . ví dụ

$query = "SELECT * FROM user WHERE name = '{$_GET['name']}' AND password = '{$_GET['pass']}'"

một cái gì đó tương tự có thể được khai thác bởi

// exmaple.com?name=me&pass=1' OR 1=1; -- 

điều này sẽ dẫn đến một câu lệnh SQL

$query = "SELECT * FROM user WHERE name = 'me' AND password = '1' OR 1=1; -- '"
//executing the SQL statement and getting the result
if($result->num_rows){
    //user is authentic
}else{
    //wrong password
}
// that SQL will always get results from the table which will be considered a correct password

Chúc bạn may mắn khi chuyển phần mềm của mình sang các câu lệnh đã chuẩn bị sẵn và hãy nhớ rằng bạn sẽ yên tâm khi biết rằng bất cứ điều gì xảy ra, bạn vẫn an toàn trước các cuộc tấn công SQL injection đáng để thay đổi các tệp nguồn




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MySQL Replication:Các giao dịch sai sót trong bản sao dựa trên GTID

  2. Chèn nhiều MYSQL trong codeigniter

  3. Đăng hàm Javascript và gọi tập lệnh php

  4. Cơ sở lý luận về MySQL Fulltext Stopwords

  5. Tải xml vào bảng mysql với phần tử