Каковы наилучшие способы защиты от MySQL-инъекций? Какие недостатки я должен искать?
Я знаю, что это такое, но я действительно не знаю, насколько я уязвим. Хотя я взял (что я думаю), чтобы защитить себя и мою базу данных.
Есть ли какой-нибудь надежный способ остановить кого-то?
BTW … Я пишу на PHP 🙂
Используйте подготовленные операторы вместо смешивания инструкции и фактических данных полезной нагрузки.
видеть
Вы также можете быть заинтересованы в http://shiflett.org/articles/sql-injection и http://shiflett.org/blog/2007/sep/the-unexpected-sql-injection
Не доверять никому!
Санируйте все входные – filter_var()
или регулярные выражения или in_array()
допустимых значений или смешанную стратегию в зависимости от типа данных.
«Вход» означает любой источник ввода, который вы не контролируете напрямую, а не только формы!
Санируйте все, что вы вернетесь из $_GET
, $_POST
, $_SESSION
, $_COOKIE
– все, что может иметь любую возможность быть испорченным.
А ТАКЖЕ
Использовать подготовленные заявления
Вы должны дезинформировать все входные данные. Как вы можете это сделать, это зависит от программирования languaguage и / или рамки, с которой вы работаете.
редактировать:
Если вы используете php, то функция, которую вы ищете, – mysql_real_escape_string ($ string). Вы должны использовать это во всем, что вы получаете от клиента, который должен войти в базу данных.
Если вы не используете фреймворк, который предоставляет вам инструменты для дезинфекции, PHP имеет встроенный escaper, вы должны начать там. Документацию можно найти в документах PHP для реальной строки escape mysql . Если вы посмотрите на третий пример, вы получите представление об основах, которым вы можете следовать.
Другим методом, который я придерживаюсь, является обеспечение того, чтобы я приводил переменные там, где это необходимо. Например, если я ожидаю ввода от пользователя целого числа, я сделаю следующее:
$age = (int)$age;
Кроме того, если столбец должен быть ограничен одним или двумя значениями (например, гендерный столбец), убедитесь, что вы применяете это на своем PHP перед тем, как поместить его в базу данных.
Это может показаться здравым смыслом, но я некоторое время спотыкался об этом.
Существует разница между кодировкой htmlentities()
и экранированием mysql_real_escape_string()
. Я думал о них как о взаимозаменяемости. Однако нет … как здравомыслящий вам расскажет. 🙂 Обычно лучше всего применять их оба, например, сначала кодировать, а затем убегать.
Затем, вытягивая данные, обратный процесс, unescape (если необходимо), затем unencode. Примечание, являющееся специфическим в том, как этапы выполняются (и наоборот), сэкономит много головных болей и проблем с двойным бегством.
Знак, что у вас может быть проблема, будет напрямую вводить пользовательский ввод и помещать его в вашу команду SQL.
Например, вы запрашиваете свое имя пользователя. Если вы возьмете это, а затем просто скажете
«Выберите * От пользователей, где Username = '$ USERNAME';"
Затем пользователь может добавить «JOE», «Drop Table …» и так далее.
В 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); }