Что именно делает PDO безопасным?

Возможный дубликат:
Как подготовленные операторы могут защитить от атак путем внедрения кода SQL?

Для тех из нас, кто плохо знаком с PDO, мы понимаем, что он более безопасен и что его лучше использовать, но я не могу понять, как это защищено?

<?php
$db = new PDO('mysql:host=localhost;dbname=testdb;charset=UTF-8', 'username', 'password');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
try {
    //connect as appropriate as above
    $db->query('hi'); //invalid query!
} catch(PDOException $ex) {
    echo "An Error occured!"; //user friendly message
    some_logging_function($ex->getMessage());
}
foreach($db->query('SELECT * FROM table') as $row) {
    echo $row['field1'].' '.$row['field2']; //etc...
}
?>

Имейте в виду, я понимаю, что он делает, но что именно он делает для очистки ввода? Я знаю, что mysql_* использует mysql_real_escape_string, который просто ставит буквальное значение \. Использует ли PDO эту же систему? Если нет, то на что мы полагаемся в плане санитарии?


person Nick    schedule 29.01.2013    source источник
comment
Не сам PDO защищает вас от SQL-инъекций. Это использование подготовленных операторов. Если вы звоните $db->query("select * from users where userid=$something_from_the_user"), вы делаете это неправильно. Суть в том, чтобы не использовать какие-либо данные при построении ваших операторов SQL.   -  person Andy Lester    schedule 29.01.2013
comment
@AndyLester плохая новость в том, что в любом более или менее сложном приложении вы не можете избежать использования динамических данных при построении ваших операторов SQL. Или это делает ваш код чрезвычайно сложным.   -  person Your Common Sense    schedule 29.01.2013
comment
Все дело в том, какую сложность вы готовы заплатить за то, чтобы не использовать небезопасные данные при создании исполняемого кода. То, что иногда за безопасность приходится платить сложностью, не новость.   -  person Andy Lester    schedule 29.01.2013


Ответы (2)


Хотя, похоже, в вашем запросе нет ничего, что можно было бы дезинфицировать. Кроме того, если вы просто введете свой запрос, он ничего не сделает с ним.

Но у него есть волшебство, называемое подготовленными утверждениями, которое действительно помогает ты. Вы можете проверить ссылку @yourcommonsense для получения дополнительной информации об этом:

Как подготовленные операторы могут защитить от атак SQL-инъекций?

person Nanne    schedule 29.01.2013
comment
Итак, что я понимаю, PDO делает два подключения к базе данных, первое с запросом, второе с пользовательским вводом? - person Nick; 29.01.2013
comment
Первый я бы назвал подготовкой, но в принципе да. Это делает соединения «n + 1» правильными, если вам нужно сделать это снова, вы можете повторно использовать уже подготовленный запрос. - person Nanne; 29.01.2013
comment
Итак, это становится его собственной переменной и соединением: $sql->prepare("SELECT * FROM users where id=?");, а затем это также становится его собственным выполнением? $db->execute($data); если это так, сопоставляет ли база данных их вместе при выполнении второго запроса? или делает ПДО? И по существу мы можем снова использовать $sql? - person Nick; 29.01.2013
comment
Спасибо вам обоим, теперь я довольно хорошо понимаю, как это работает, все еще немного запутался в синтаксисе подготовленного выполнения и т. д., но, вероятно, будет лучше, если я выясню это самостоятельно. - person Nick; 29.01.2013
comment
@JohnDoe, здесь есть примеры использования PDO prepare() с последующим execute(): php.net/manual/en/pdo.prepare.php - person Bill Karwin; 29.01.2013

PDO имеет метод PDO::Quote(), который выполняет ту же работу, что и mysql_real_escape_string(). Это обеспечивает в основном ту же функциональность и уровень безопасности sme.

Лучшим вариантом является функция «Подготовленные операторы», когда вы помещаете в запрос маркеры, а не переменные, используя PDO::prepare(), а затем используете PDO::execute() для передачи переменных в запрос.

Это более безопасно, поскольку использует внутренние механизмы ядра базы данных для передачи переменных в запрос. Существует нулевая вероятность атаки SQL-инъекцией через подготовленный оператор (если только в самом механизме базы данных нет ошибки, но это то, что вы могли бы смягчить, обновив версию MySQL; ничего общего с вашим собственным кодом).

Подготовленные операторы также имеют то преимущество, что они могут кэшироваться механизмом базы данных. Это означает, что если вы делаете несколько вызовов, используя один и тот же запрос, но с разными значениями переменных, вы получите прирост производительности по сравнению с теми же запросами, используя старый механизм на основе строк.

Примечание. Некоторые БД могут изначально не поддерживать подготовленные операторы, и в этом случае PHP будет их эмулировать. В этом случае это в основном то же самое, что и при использовании PDO::Quote, и вы не получаете перечисленных выше преимуществ. Большинство баз данных поддерживают их, но даже в этом случае их можно отключить, поэтому убедитесь, что вы отключили ATTR_EMULATE_PREPARES.

Наконец, использование PDO более безопасно, поскольку в основе старого расширения mysql лежали некоторые фундаментальные проблемы безопасности. Например, старый API не шифрует обмен данными между PHP и базой данных MySQL. Это означает, что существует теоретический риск атаки перехватчика, особенно если БД не находится на том же сервере, что и PHP. PDO использует более новую версию протокола связи MySQL и, таким образом, может шифровать этот трафик и, как следствие, более безопасен (а также почему PDO не поддерживает действительно старые версии MySQL). Есть несколько других подобных скрытых рисков со старым API, которые настолько глубоко укоренились в коде, что их нельзя было удалить. Вот почему расширение mysqli было написано как его прямая замена.

person SDC    schedule 29.01.2013
comment
1. Метод PDO::Quote() выполняет НЕ ту же работу, что и mysql_real_escape_string(), и между ними есть существенная разница. 2. подготовленные операторы не более безопасны, чем правильное форматирование. Они равны. 3. Обычное веб-приложение не делает несколько вызовов по одному и тому же запросу, поэтому никаких бустов. 4. Что это за горстка других подобных скрытых рисков? - person Your Common Sense; 29.01.2013
comment
@YourCommonSense - 1. Да, я знаю, что они разные, но примерно играют одну и ту же роль. 2. Да, это так: строковый запрос в кавычках сохраняет теоретический риск атаки путем внедрения на основе набора символов; подготовленные отчеты - нет. 3. Я написал несколько веб-приложений, которые вызывают подготовленный запрос в цикле. Я получил импульс от этого. 4. Мне нужно пойти и откопать ссылки, и у меня действительно нет времени. Но шифрование было главным. - person SDC; 29.01.2013