Как мы узнаем, что PDO избегает SQL-инъекций?

Я новичок в библиотеках PDO. Я работаю над средой разработки с MySQL в качестве моей базы данных. Я могу выполнять свои запросы, используя функцию подготовки и выполнения, используя знак "?" placeholder, а также метод bindParam при использовании именованных заполнителей (например: ": column").

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

Я попытался выполнить var_dump $ result-> execute () и $ result-> fetch (), но оператор execute дает мне sql моего оператора подготовки с заполнителями, в то время как оператор fetch дает мне результат этого запроса.

Есть ли способ посмотреть на запрос поиска, который будет запущен, или, по крайней мере, как будут выглядеть параметры перед запуском запроса?

Надеюсь, я понял свой вопрос. : |


person macha    schedule 07.01.2011    source источник
comment
Вы слишком сильно переживаете. Подготовленные операторы ускользают от вашего ввода на 100%. Если вам нужно увидеть, как выглядит окончательный запрос, вам необходимо настроить журнал запросов к базе данных.   -  person netcoder    schedule 07.01.2011
comment
@netcoder Подготовленные операторы ничего не экранируют (если только они не находятся в совместимом режиме). И в журнале запросов нет ничего нового   -  person Your Common Sense    schedule 07.01.2011
comment
@Col. Шрапнель: Технически да, это так, хотя вы можете выразить это так, как хотите. Насчет того, что в журнале запросов нет ничего нового, я просто не понимаю, что это значит ...   -  person netcoder    schedule 07.01.2011
comment
@netcoder Нет, это не так. Технически или буквально, или что угодно. Ниже есть ссылка на то, как работают подготовленные операторы, вы найдете это очень поучительным. Пожалуйста, не комментируйте, пока не изучите его внимательно и не попытаетесь запустить код из него.   -  person Your Common Sense    schedule 07.01.2011
comment
@Col. Shrapnel: это вопрос PDO, и подготовленные операторы yes в PDO избегают ввода. Пожалуйста, не комментируйте, пока не научитесь дипломатии.   -  person netcoder    schedule 07.01.2011
comment
@netcoder Я ненавижу дипломатию, когда встречаю невежество   -  person Your Common Sense    schedule 07.01.2011


Ответы (4)


Когда вы пишете что-то вроде:

$stmt = $pdo->prepare('SELECT * FROM tbl_name WHERE col_name = :col_name;');
$stmt->bindValue('col_name', 'some \' value');
$stmt->execute();

Фактический запрос ... SELECT * FROM tbl_name WHERE col_name = :col_name;. Это называется подготовленным оператором. Сначала вы отправляете запрос в базу данных, а затем отправляете параметры запроса. PDO не объединяет запрос и параметры.

Вы, наверное, думали, что PDOStatement::bindValue() делает что-то вроде:

public function bindValue($placeholer, $value, $valueType = PDO::PARAM_STR) {
    $this->query = str_replace($placeholder, $this->quote($value, $valueType), $this->query);
}

Но это не.

Он делает что-то вроде этого:

public function execute() {
    try {
        $this->sendQueryToDatabase($this->query);

        // Query is valid
        $this->sendParametersToDatabase($this->parameters);

        return $this->fetchResultSet();
    } catch (... $e) {
        // Query is invalid (eg. syntax error)
        throw ...;
    }
}

Подробнее о подготовленных отчетах

person Crozin    schedule 07.01.2011
comment
Итак, как мы узнаем, безопасны ли отправляемые параметры? нам нужно проверить их перед рукой ??? - person macha; 07.01.2011
comment
Параметры не могут быть небезопасными, поскольку они не являются частью запроса. Это просто необработанные данные. - person Crozin; 07.01.2011
comment
эй, я знаю, что это может быть слишком высокий уровень, есть ли у вас какие-либо представления о том, как будет анализироваться запрос, а затем как эти параметры будут отправлены / заменены заполнителями? - person macha; 07.01.2011
comment
Запрос и его параметры отправляются отдельно, и я думаю, они никогда не объединяются (вам нужно изучить исходные коды MySQL, чтобы узнать, как именно он работает). Даже если какой-либо параметр содержит ' OR do badCode --, он будет рассматриваться как необработанный текст, и такое значение будет вставлено в столбец. - person Crozin; 07.01.2011
comment
если параметр, как вы сказали, «Или сделать плохой код» - передан, это повредит базу данных, правильно ?? поскольку побега не будет? - person macha; 07.01.2011
comment
Нет, если он обрабатывается как необработанный текст, поскольку база данных никогда не попытается проанализировать параметр запроса. По сути, это похоже на то, как $var = 'system("ls");'; на самом деле не оценивает php-код в $ var. Это просто данные = - person Christopher Tarquini; 07.01.2011
comment
Хорошо! Спасибо всем за терпение и за объяснения. - person macha; 07.01.2011

Проще говоря.

PDO имеет 2 режима выполнения подготовленных операторов:

  1. Родной режим. Запрос и данные отправляются в базу данных раздельно. Это означает, что данные никогда не добавляются в запрос. Итак, вреда причинить нельзя. Всегда. Запрос отправляется в базу данных как есть, с отметками ? (но без именованных заполнителей, которые заменяются PDO с ?s)
  2. Режим совместимости. PDO делает запрос в старом стиле, заменяя заполнители связанными переменными, зависящими от имени переменной. Строки заключаются в кавычки / экранируются, остальные приводятся к его типу.

Оба метода совершенно безопасны.

Настоящая опасность начинается, когда у вас есть переменный идентификатор ...

person Your Common Sense    schedule 07.01.2011
comment
чем опасен идентификатор переменной ?? Я думал, что это безопаснее, ведь мы даже проверяем тип данных? - person macha; 07.01.2011
comment
@macha Я имею в виду название поля. Например SELECT * FROM table ORDER BY $column_name действительно опасен - person Your Common Sense; 07.01.2011

Оператор подготовки обрабатывается mysql, поэтому pdo не избегает запроса, pdo отправляет запрос и "после" параметра

person kinnou02    schedule 07.01.2011
comment
Не знаю, почему вам отказывают в голосовании, это действительно так. - person netcoder; 07.01.2011
comment
На самом деле это не так, PDO обычно эмулирует подготовленные операторы, поскольку подготовленные операторы на стороне сервера, хотя и поддерживаются, обычно не являются хорошей идеей. - person MarkR; 07.01.2011
comment
Подготовленные на стороне сервера операторы плохи; они обычно приводят к худшей производительности и меньшей надежности, но вы можете найти и другое. Но это нормально, PDO не нужно их использовать, эмуляция - это хорошо. - person MarkR; 07.01.2011
comment
Я отклонил этот ответ, потому что искаженный язык не позволяет мне понять, что говорится на плакате, несмотря на то, что я понимаю, как работают подготовленные утверждения. - person Conspicuous Compiler; 24.01.2011

Включите общий журнал запросов и наблюдайте за запросами, которые фактически выполняются на сервере, когда вы запускаете простые операторы - сделайте некоторые вставки, например, со строками, содержащими встроенные кавычки или пустые значения.

person MarkR    schedule 07.01.2011