Можно ли полностью предотвратить внедрение SQL с помощью оператора PDO Prepared без bind_param? - PullRequest
6 голосов
/ 27 октября 2011

Я очень новичок в PDO, извините, если вы чувствуете, что задаю глупый вопрос.Обычный и простой PDO Подготовленное заявление без Bind_param :

$sql = $db->prepare('SELECT * FROM employees WHERE name = ?');
$sql->execute(array($name));
$rows = $sql->fetchAll();

с Bind_param :

$sql->bind_param("s", $name); //s means the database expects a string

Я слышал, как люди говорили: «Защита происходит от использования связанных параметров, а не от использования подготовленного утверждения» .Могу ли я узнать, что такое связанные параметры ? Bind_param является связанным параметром ?Если да, то обычный и простой оператор PDO Prepared без Bind_param НЕ МОЖЕТ полностью предотвратить внедрение SQL?

Ответы [ 6 ]

6 голосов
/ 27 октября 2011

Вы делаете это правильно.Связанные параметры - это параметры, объявленные в «подготовленном операторе» с использованием?.Затем они связываются с использованием execute () со своим значением в качестве параметра, который будет связан с оператором.

2 голосов
/ 27 октября 2011

Защита происходит от использования связанных параметров, а не от использования подготовленного оператора

Означает, что недостаточно просто использовать prepare (), но держать запрос свсе переменные в нем примерно такие:

$sql = $db->prepare("SELECT * FROM employees WHERE name ='$name'");
$sql->execute();
$rows = $sql->fetchAll();

Кто-то, кто сказал, что это означает, что хотя вы технически используете здесь подготовленное утверждение, вы не привязываете переменные к нему.Таким образом, запрос все равно становится уязвимым.

Чтобы быть защищенным, необходимо заменить все переменные в запросе заполнителями, а затем связать эти переменные:

$sql = $db->prepare("SELECT * FROM employees WHERE name = ?");
$sql->bindParam(1, $name);
$sql->execute();
$rows = $sql->fetchAll();

Но PDOимеет приятное сокращение для привязки, позволяющее вам избежать повторяющихся вызовов pindParam (), выполняющих все эти вызовы внутри себя, когда вы отправляете переменные в execute ():

$sql = $db->prepare('SELECT * FROM employees WHERE name = ?');
$sql->execute(array($name));
$rows = $sql->fetchAll();

По сути, это такое же связывание, какbindParam () делает. Таким образом, ваш код использует привязку и поэтому безопасен

Наконец, bind_param () на самом деле является функцией mysqli и вообще не имеет ничего общего с PDO.

2 голосов
/ 27 октября 2011

Это правда.

У меня нет никакой экспертной информации по этому вопросу, но насколько я понимаю, проблема с внедрением SQL заключается в том, что сервер SQL получает строку и считает ее истинной. Сервер не имеет возможности узнать, были ли, например, команды DUMP преднамеренно или нет.

С привязанными параметрами вы говорите серверу SQL: «Эй, смотри, это запрос, и я ожидаю, что параметры здесь, здесь и там. Да, кстати, вот значения» Этот подход отличается тем, что SQL теперь знает фактическое выражение, которое он должен выполнить, и каковы значения. Это позволяет SQL вставлять значения в выражение без изменения самого выражения.

1 голос
/ 01 марта 2016

OWASP дал мне то же самое сомнение, следуя их рекомендациям по внедрению SQL " SQL_Injection_Prevention_Cheat_Sheet " они говорят:

Вариант защиты 1: подготовленные операторы (с параметризованными запросами):

  • PHP - использовать PDO со строго типизированными параметризованными запросами (используя bindParam ())

так что кажется, что вы должны использовать bind_param () всегда. Я не использую его, потому что я конвертировал тысячи уязвимых DAO с помощью автоматического скрипта, и bind_param () потребовал бы от меня их всех вручную отредактировать.

Я еще не видел примеров инъекций без использования bind_param (), поэтому я уверен, что в этом нет необходимости.

0 голосов
/ 23 февраля 2019

Да, вам НЕ нужно связывать параметры, чтобы убедиться, что вы защищены от атак SQL-инъекций. Руководство говорит нам: «Кроме того, вызов PDO :: prepare () и PDOStatement :: execute () помогает предотвратить атаки SQL-инъекций, устраняя необходимость вручную заключать в кавычки и экранировать параметры». - PDO :: подготовить . Достаточно сказано.

Связывание параметров - это просто удобный способ повторного использования вашего SQL-запроса - вы можете связать что угодно с вашими «заполнителями», как только вы поместите их в ваш SQL-запрос - отличный пример здесь: *.

Но опять же, работа выполняется с использованием prepare и execute.

0 голосов
/ 27 октября 2011

Вы делаете это правильно.

неправильно путь:

$sql = $db->query('SELECT * FROM employees WHERE name = '.$name); //WRONG WRONG HORRIBLE
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...