Защита от инъекций MySQL и признаки уязвимости с использованием PHP
Каковы наилучшие способы защиты от внедрения MySQL? На какие слабые стороны мне следует обратить внимание?
Я знаю, что это такое, но я действительно понятия не имею, насколько уязвимым я могу быть. Хотя я предпринял (как мне кажется) шаги по защите себя и своей базы данных.
Есть ли какой-нибудь верный способ остановить кого-нибудь?
КСТАТИ... Я пишу на PHP:)
7 answers
Используйте подготовленные инструкции вместо смешивания инструкции и фактических данных полезной нагрузки.
См.
- http://dev.mysql.com/tech-resources/articles/4.1/prepared-statements.html
- PDO::подготовить
- mysqli::подготовить
Вас также может заинтересовать http://shiflett.org/articles/sql-injection и http://shiflett.org/blog/2007/sep/the-unexpected-sql-injection
Никому не доверяй!
Очистите все входные данные - filter_var()
или регулярные выражения или in_array()
допустимых значений или смешанную стратегию в зависимости от типа данных.
"Ввод" означает любой источник ввода, которым вы непосредственно не управляете, а не только формы!
Дезинфицируйте все, из чего вы возвращаетесь $_GET
, $_POST
, $_SESSION
, $_COOKIE
-- все, что может иметь хоть малейшую возможность быть испорченным.
И
Используйте подготовленные инструкции
Вы должны очистить все входные данные. Как вы можете это сделать, зависит от языка программирования и/или платформы, с которой вы работаете.
Изменить:
Если вы используете php, то функция, которую вы ищете, - это mysql_real_escape_string($строка). Вы должны использовать это для всего, что вы получаете от клиента, что должно быть внесено в базу данных.
Если вы не используете фреймворк, предоставляющий вам инструменты очистки, в PHP есть встроенный экранирующий механизм строк, вам следует начать с этого. Вы можете найти документацию по этому в PHP docs для mysql реальная escape-строка. Если вы посмотрите на пример три, вы получите хорошее представление об основах, которым вы можете следовать.
Другой метод, которому я следую, заключается в том, чтобы убедиться, что я отбрасываю переменные там, где это уместно. Например, если я ожидаю, что ввод от пользователя будет целым числом, я сделаю следующее:
$age = (int)$age;
Также, если предполагается, что столбец ограничен одним или двумя значениями (например, столбец пола), убедитесь, что вы применяете это в своем PHP, прежде чем помещать его в базу данных.
Это может показаться здравым смыслом, но я на какое-то время запутался в этом.
Существует разница между кодированием htmlentities()
и убегающий mysql_real_escape_string()
. Я думал о них как о вполне взаимозаменяемых. Однако там нет... как вам подскажет здравый смысл. :) Обычно лучше всего применять их оба, например, сначала кодировать, а затем экранировать.
Затем при извлечении данных выполните обратный процесс, снимите эскейп (при необходимости), а затем снимите код. Обратите внимание на то, как конкретно выполняются шаги выполняются (и отменяются), избавят от многих головных болей и двойных неприятностей.
Признаком того, что у вас может возникнуть проблема, было бы непосредственное использование пользовательского ввода и включение его в вашу команду SQL.
Например, вы спрашиваете их имя пользователя. Если вы возьмете его, а затем просто скажете
"Выберите * Из пользователей, где Имя пользователя = '$ИМЯ ПОЛЬЗОВАТЕЛЯ';"
Затем пользователь может добавить "ДЖО"; Удалить таблицу..." и так далее.
На perl вы можете сказать что-то вроде
my $sth2 = $dbh->prepare("Insert Into HostList (HostName,PollTime,Status) values (?,?,?);");
$sth2->execute($Hostname,$myDate,$Status);
Затем метод execute будет искать эксплойты, подобные приведенному выше, и избегать их должным образом.
Я использую эту функцию PHP для всех входных данных, прежде чем пытаться использовать ее в любом коде (запрос MySQL, отображение данных и т.д.). Вероятно, она не завершена, но она должна остановить все основные попытки взлома системы:
//$linkID is the link ID of the connection to the MySQL database
function clean_input($input)
{
GLOBAL $linkID;
if(get_magic_quotes_gpc())
{
//Remove slashes that were used to escape characters in post.
$input = stripslashes($input);
}
//Remove ALL HTML tags to prevent XSS and abuse of the system.
$input = strip_tags($input);
//Escape the string for insertion into a MySQL query, and return it.
return mysql_real_escape_string($input,$linkID);
}