Что делает bind param?


Я учусь избегать 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

Author: Community, 2013-08-25

2 answers

Теперь, предполагая, что эти 4 переменные были введены пользователем, я не понимаю , как это предотвращает SQL-инъекции. Насколько я понимаю, они все еще могут вводить туда все, что захотят.

Основной принцип заключается в использовании подготовленного оператора, который предназначен для отправки безопасного запроса на сервер бд, это можно сделать, экранировав пользовательский ввод, который не является частью реального запроса, а также проверив запрос без какого-либо (предложения 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

Используя подготовленную инструкцию, сервер бд проверит запрос без какого-либо параметра, на этом этапе ошибки могут быть обнаружены до привязки любого параметра, затем, если запрос был действительным, параметры также будут отправлены на сервер для завершения запроса.

Из Руководства по PHP http://php.net/manual/en/mysqli.quickstart.prepared-statements.php:

Побег и внедрение 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())

 14
Author: Community, 2017-05-23 11:47:05

Используя подготовленные инструкции, вы отделяете SQL-запросы от введенных пользователем данных. Вместо входных данных вы помещаете заполнители (символ '?') в свой SQL-запрос. Затем вы отправляете запрос на сервер СУБД (например, MySQL) с помощью метода "mysqli::prepare". Таким образом, сервер проверяет, все ли в порядке, и, если это так, он ожидает ввода данных. К настоящему времени он уже знает ваш запрос. Просто ему нужно дождаться, пока входные данные будут привязаны к запросу.

В этот момент "bind_param" вступает в действие, связывающее заполнители с введенными пользователем данными. Обратите внимание, что bind_param привязывает данные только к заполнителям, оставляя запрос неизменным. Таким образом, нет способа изменить исходный SQL-запрос, потому что он уже отправлен на сервер с помощью метода подготовки и потому что вы отправляете SQL-запросы и входные данные отдельно, чтобы введенные пользователем данные не могли мешать запросам.

В ЛЮБОМ СЛУЧАЕ...

Фактическая цель использования подготовленного оператора в SQL состоит в том, чтобы сократить стоимость обработка запросов, А НЕ для отделения данных от запроса. Именно так он используется сейчас, а не так, как он был разработан для использования в первую очередь.

"sssd" означает "строка", "строка", "строка" и "двойной". На самом деле: $код - это строка, $язык - это строка, $официальный - это строка, а $процент - это двойной тип.

Строка Mysqli_real_escape_string не устарела, но строка mysql_real_escape_string устарела (первая - MYSQLI, где I означает "улучшенный").

 10
Author: italian developer, 2014-01-07 19:12:52