Я учусь об исключении SQL-инъекций, и я немного смущен.
При использовании bind_param я не понимаю цели. На странице руководства я нашел этот пример:
$stmt = mysqli_prepare($link, "INSERT INTO CountryLanguage VALUES (?, ?, ?, ?)"); mysqli_stmt_bind_param($stmt, 'sssd', $code, $language, $official, $percent); $code = 'DEU'; $language = 'Bavarian'; $official = "F"; $percent = 11.2;
Теперь, если предположить, что эти 4 переменные были введены пользователем, я не понимаю, как это предотвращает SQL-инъекции. По моему мнению, они все еще могут вводить все, что захотят.
Я также не могу найти объяснение для 'sssd'
там. Что оно делает? Это то, что делает его безопасным?
Заключительный вопрос: я прочитал еще один вопрос о том, что mysqli_real_escape_string
устарел, но он не говорит об этом в руководстве. Как он устарел? Не может ли он почему-то избежать специальных символов?
Примечание. Этот вопрос объясняет, что делает bind_param, но я до сих пор не понимаю, почему он более безопасен или более защищен. Объяснение Bind_param
Теперь, если предположить, что эти 4 переменные были введены пользователем, я не понимаю, как это предотвращает SQL-инъекции. По моему мнению, они все еще могут вводить все, что захотят.
Основным принципом является использование подготовленного оператора, который предназначен для отправки безопасного запроса на сервер db, это можно сделать, экранировав вход пользователя, который не является частью реального запроса, а также проверит запрос без какого-либо предложения where (where) действительность запроса перед использованием любых параметров.
Из этого вопроса: PDO отправляет необработанный запрос в MySQL, а Mysqli отправляет подготовленный запрос, оба дают тот же результат
$stmt = $mysqli->prepare("SELECT * FROM users WHERE username =?")) { $stmt->bind_param("i", $user); $user = "''1''";
серверные журналы:
130802 23:39:39 175 Connect ****@localhost on testdb 175 Prepare SELECT * FROM users WHERE username =? 175 Execute SELECT * FROM users WHERE username =0 175 Quit
Используя подготовленный оператор, сервер db будет проверять запрос без каких-либо параметров, на этом этапе ошибки могут быть обнаружены до привязки какого-либо параметра, а затем, если запрос был прав, параметры также будут отправляться на сервер для завершения запроса.
Из руководства PHP http://php.net/manual/en/mysqli.quickstart.prepared-statements.php :
Escaping и SQL-инъекция
Связанные переменные автоматически экранируются сервером. Сервер вставляет свои экранированные значения в соответствующие места в шаблон оператора перед выполнением. Чтобы создать соответствующее преобразование, сервер должен указать подсказку для типа связанной переменной. Дополнительную информацию см. В функции mysqli_stmt_bind_param ().
..
Я также не могу найти объяснение для 'sssd' там. Что оно делает? Это то, что делает его безопасным?
Ответ здесь: http://php.net/manual/en/mysqli-stmt.bind-param.php
i corresponding variable has type integer d corresponding variable has type double s corresponding variable has type string b corresponding variable is a blob and will be sent in packets
Заключительный вопрос: я прочитал еще один вопрос о том, что mysqli_real_escape_string устарел, но он не говорит об этом в руководстве. Как он устарел? Не может ли он почему-то избежать специальных символов?
Можете ли вы дать ссылку? Я думаю, вы неправильно поняли ( mysql_real_escape_string()
)
Используя подготовленные операторы, вы отделяете SQL-запросы от введенных пользователем данных. Вместо входных данных вы помещаете заполнители ('?' Char) в свой SQL-запрос. Затем вы отправляете запрос на сервер СУБД (например: MySQL) с помощью метода «mysqli :: prepare». Поэтому сервер проверяет, что все в порядке, и если да, то ожидает входных данных. К настоящему времени он уже знает ваш запрос. Просто он должен ждать ввода данных для привязки к запросу.
На данный момент вступает в действие «bind_param», привязывание заполнителей к введенным пользователем данным. Обратите внимание, что bind_param связывает данные только с заполнителями, оставляя неизменным запрос . Таким образом, нет способа изменить исходный SQL-запрос, поскольку он уже отправлен на сервер с помощью метода подготовки и потому, что вы отправляете SQL-запросы и вводите данные отдельно, так что введенные пользователем данные не могут мешать запросам.
ТАК ИЛИ ИНАЧЕ…
Фактическая цель использования подготовленного оператора в SQL – это сократить затраты на обработку запросов, а не на разделение данных из запроса. Именно так оно используется сейчас, а не как оно предназначено для использования в первую очередь.
«sssd» означает «string», «string», «string» и «double». На самом деле: $ code – строка, $ language – строка, $ official – строка, а $ percent – двойной тип.
mysqli_real_escape_string не устарел, но mysql_real_escape_string устарел (первый из них – mysqlI, где я обозначаю «улучшенный»).