Является ли mysql_real_escape_string
достаточным для очистки ввода пользователя в большинстве ситуаций?
::РЕДАКТИРОВАТЬ::
Я имею в виду главным образом с точки зрения предотвращения SQL-инъекции, но в конечном итоге хочу знать, могу ли я доверять пользовательским данным после применения mysql_real_escape_string или если я должен принять дополнительные меры для очистки данных, прежде чем передавать их вокруг приложения и баз данных.
Я вижу, что очистка для символов HTML важна, но я бы не счел нужным доверять пользователю.
T
mysql_real_escape_string
недостаточно во всех ситуациях, но это, безусловно, очень хороший друг. Лучшее решение – это подготовленные заявления
//example from http://php.net/manual/en/pdo.prepared-statements.php $stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (?, ?)"); $stmt->bindParam(1, $name); $stmt->bindParam(2, $value); // insert one row $name = 'one'; $value = 1; $stmt->execute();
Кроме того, не забывайте HTMLPurifier, который можно использовать для отбрасывания любых недопустимых / подозрительных символов.
………..
Изменить: основываясь на приведенных ниже комментариях, мне нужно опубликовать эту ссылку (я должен был сделать это раньше, чем пожалеть о создании путаницы)
mysql_real_escape_string () по сравнению с подготовленными заявлениями
Цитирование:
mysql_real_escape_string () подвержен тем же самым проблемам, что и для addlashes ().
Крис Шифлетт (эксперт по безопасности)
Ответ на ваш вопрос: № mysql_real_escape_string () не подходит для всех пользовательских входных данных, а mysql_real_escape_string () не останавливает всю SQL-инъекцию. addslashes () – еще одна популярная функция, используемая в php, и имеет ту же проблему.
уязвимый код:
mysql_query("select * from user where id=".mysql_real_escape_string($_GET[id]));
poc exploit:
http://localhost/sql_test.php?id=1 or sleep(500)
Патч должен использовать кавычки вокруг id:
mysql_query("select * from user where id='".mysql_real_escape_string($_GET[id])."'");
На самом деле наилучшим подходом является использование параметризованных запросов, о которых указывал ряд людей. Pdo работает хорошо, adodb – еще одна популярная библиотека для php.
Если вы используете mysql_real_escape_string, его следует использовать только для SQL-инъекции и ничего больше. Уязвимости сильно зависят от того, как используются данные. Следует применять меры безопасности по функции по функциям. И да, XSS – ОЧЕНЬ СЕРЬЕЗНАЯ ПРОБЛЕМА . Не фильтровать для html – это серьезная ошибка, которую хакер будет использовать для pw3n. Пожалуйста, прочтите xss faq .
В базу данных, да. Вы также захотите рассмотреть возможность адекватного вывода / кодирования данных для вывода.
Вы также должны рассмотреть возможность проверки ввода в соответствии с тем, что вы ожидаете.
Рассматривали ли вы использование подготовленных заявлений ? PHP предлагает множество способов взаимодействия с вашей базой данных. Большинство из них лучше, чем функции mysql_ *.
PDO , MDB2 и MySQL Improved должны начать работу.
Какие ситуации?
Для SQL-запросов это замечательно. (Подготовленные утверждения лучше – я голосую за PDO для этого, но функция отлично справляется.) Для HTML и т. П. Это не инструмент для задания – попробуйте общие htmlspecialchars
или более точный инструмент, например, HTML Cleanifier .
Чтобы обратиться к редактированию : единственным добавленным слоем является добавление данных, например, подтверждение того, что если вы помещаете целое число в базу данных и ожидаете положительного целого числа, вы возвращаете пользователю ошибку при попытке ввести отрицательное целое число. Что касается целостности данных, то mysql_real_escape_string
лучше всего подходит для экранирования (хотя, опять же, подготовленные операторы – это более чистая система, которая позволяет избежать экранирования полностью).
mysql_real_escape_string()
полезен только для предотвращения атак SQL-инъекций. Это не поможет вам предотвратить атаки на сценарии межсайтового сценария. Для этого вы должны использовать htmlspecialchars()
непосредственно перед выводом данных, которые были первоначально собраны с пользовательского ввода.
Существует два способа: использовать подготовленные операторы (как указано в других ответах), но это замедлит ваше приложение, потому что теперь вам нужно отправить два запроса в базу данных, а не в одну. Если вы можете жить с пониженной производительностью, то идите на это; Подготовленные заявления делают ваш код более красивым и понятным.
Если вы решили использовать mysql_real_escape_string, убедитесь, что вы избегаете всех ненадежных строк. Сжатая строка (mysql_real_escape_string) – это безопасная SQL-инъекция . Если вы не избежите всех строк, тогда вы не защищены. Вы действительно должны объединить mysql_real_escape_string с проверкой ввода; проверяя, что переменная, которую вы ожидаете провести на самом деле, представляет собой число и в пределах ожидаемого диапазона. Помните, никогда не доверяйте пользователю.
Существуют разные типы «очистки».
mysql_real_escape_string достаточно для данных базы данных, но все равно будет оцениваться браузером при отображении, если это HTML.
Чтобы удалить HTML с пользовательского ввода, вы можете использовать strip_tags .
Я бы предложил вам использовать PDO вместо обычного материала MySQL, поскольку он поддерживает подготовленные операторы прямо из коробки, а те, которые обрабатывают экранирование недействительных данных для вас.
Вы можете попробовать оба, как в
function clean_input($instr) { // Note that PHP performs addslashes() on GET/POST data. // Avoid double escaping by checking the setting before doing this. if(get_magic_quotes_gpc()) { $str = stripslashes($instr); } return mysql_real_escape_string(strip_tags(trim($instr))); }
Лучше всего было бы использовать подготовленные заявления
Я думал, что добавлю, что PHP 5.2+ имеет функции входных фильтров, которые могут дезинформировать вход пользователя различными способами.
Вот ручная запись, а также сообщение в блоге [Matt Butcher] о том, почему они великолепны.