Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Общие вопросы > pdo подготовленные выражения


Автор: titanrem 15.8.2011, 13:21
Объясните, пожалуйста, каким образом подготовленные выражения защищают от атак? Везде эта фраза встречается, но не совсем понятно. Я так понимаю, что вместо шаблонов просто подставляются определенные выражения, а где же тут защита?

Автор: titanrem 16.8.2011, 12:49
Что же тут нет ни одного человека, кто понимает, что такое подготовленные выражения и не  может ответить на вопрос?

Автор: Muerto 16.8.2011, 13:05
Смотри в сторноу prepare и execute

выражение выглдядит так $statment = SELECT * FROM test WHERE id = ?

а затем делаешь bind, (statment, 1)
Затем 
execute


Код

$sth = $dbh->prepare('SELECT name, colour, calories
    FROM fruit
    WHERE calories < ? AND colour = ?');
$sth->bindParam(1, $calories, PDO::PARAM_INT);
$sth->bindParam(2, $colour, PDO::PARAM_STR, 12);
$sth->execute();

//или как вариант с именами

$calories = 150;
$colour = 'red';
$sth = $dbh->prepare('SELECT name, colour, calories
    FROM fruit
    WHERE calories < :calories AND colour = :colour');
$sth->bindParam(':calories', $calories, PDO::PARAM_INT);
$sth->bindParam(':colour', $colour, PDO::PARAM_STR, 12);
$sth->execute();

Автор: titanrem 16.8.2011, 14:11
вот код, правда на mysqli. Но  это в данный момент не важно, и он не выполнился. А почему? Что ему такой код не дает выполнить?

Код

<?php
        $mysqli = new mysqli('localhost', 'root', '123', 'test'); 

/* Проверка соединения */ 
if (mysqli_connect_errno()) { 
    printf("Подключение невозможно: %s\n", mysqli_connect_error()); 
    exit(); 
} 

$stmt = $mysqli->prepare("select * from xxx where t=?"); 
$stmt->bind_param('s', $str); 
$str="'x' or 1=1";

/* выполнение подготовленного выражения  */ 
$stmt->execute(); 
$stmt->store_result();
printf("%d Rows.\n", $stmt->num_rows); 

/* Закрытие соединения и выражения*/ 
$stmt->close();
        ?>

Автор: titanrem 16.8.2011, 14:27
Просто интересно, что не дает выполнить такой запрос? Если без подготовленных выражений, то запрос выполняется.

Автор: skyboy 17.8.2011, 08:19
в смысле "не выполнился"? ошибка? приводи её текст.

Автор: titanrem 17.8.2011, 21:08
Нет ошибки нет, просто не возвращает строки.
Пишет 0 Rows.
Хотя реально там есть такая строка. Если убрать подготовленные выражения, и написать запрос напрямую, то все будет работать правильно.

Автор: Valinur 17.8.2011, 23:34
Код

$str="x or 1=1"


поправь и будет работать

Автор: titanrem 19.8.2011, 19:20
А зачем кавычки убирать, тогда он пишет ошибку

Автор: NewDima 20.8.2011, 05:14
Брр, зачем так все путать?
prepared statements используются для того, чтобы не парсить один и тот же запрос несколько за, а использовать его. Есть такое понятие, как стратегия запроса.
Если каждый раз передавать запрос в базу данных, то СУБД будет каждый раз составлять стратегию, как делать выборку. Повторять лишнее действие. Но можно миновать этот шаг, и заставить распарсить независимо от того,какие параметры будут передаваться в будущем. Т.е. после этого
$stmt = $mysqli->prepare("select * from xxx where t=?");
в СУБД, абстрактно говоря, будет существовать некая стратегия запроса, которая будет требовать только значения параметров. О строке "select * from xxx where t=?" на уже ничего знать не будет. Поэтому когда будете передавать параметр для совершения запроса, строка запроса не станет такой:
select * from xxx where t='x' or 1=1
потому-что эта строка вообще использоваться не будет. Поэтому в таком случае инъекция не возможна, стратегия запроса создана НЕЗАВИСИМО от того, какие конкретные значения параметров будут переданы. Это один плюс. А второй - экономия времени выполнения запроса на устранении шага постоянного составления стратегии запроса.
В mysql стратегию запроса можно увидеть с помощью команды explain

Автор: Muerto 26.8.2011, 17:03
Это не будет пахать 
Код

$str="'x' or 1=1";


Потому что за место знака ?
Должно подставится
t=''x' or 1=1'

Но я думаю там ещё идет addslashes, так что будет  t='\'x\' or 1=1'

Вот это и ответ на вопрос как защищает!
Просто отфильтрует как простой безопасный текст.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)