PHP: Является ли mysql_real_escape_string достаточным для очистки ввода пользователя?
Является ли mysql_real_escape_string
достаточным для очистки ввода пользователя в большинстве ситуаций?
:: EDIT::
Я имею в виду главным образом с точки зрения предотвращения внедрения SQL, но в конечном итоге хочу знать, могу ли я доверять пользовательским данным после применения mysql_real_escape_string или если я должен предпринять дополнительные меры для очистки данных, прежде чем передавать их вокруг приложения и баз данных,
Я вижу, что очистка для символов HTML важна, но я бы не счел нужным доверять пользователю.
Т
Ответы
Ответ 1
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, который можно использовать для удаления любых недопустимых/подозрительных символов.
...........
Edit:
Основываясь на приведенных ниже комментариях, мне нужно опубликовать эту ссылку (я должен был сделать это раньше, чем сожалеть о создании путаницы)
mysql_real_escape_string() по сравнению с подготовленными сообщениями
Цитирование:
mysql_real_escape_string(), подверженный такие же проблемы, затрагивающие addslashes().
Крис Шифлетт (эксперт по безопасности)
Ответ 2
Ответ на ваш вопрос: Нет. 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.
Ответ 3
В базу данных да. Вы также захотите рассмотреть адекватные данные об экранировании/кодировании для вывода.
Вы также должны рассмотреть возможность проверки ввода в соответствии с тем, что вы ожидаете.
Считаете ли вы использование подготовленных отчетов? PHP предлагает множество способов взаимодействия с вашей базой данных. Большинство из них лучше, чем функции mysql_ *.
PDO, MDB2 и Улучшено MySQL, чтобы вы начали.
Ответ 4
Какие ситуации?
Для SQL-запросов это здорово. (Подготовленные утверждения лучше - я голосую PDO для этого, но функция просто исчезает.) Для HTML и т.п. Это а не инструмент для работы - попробуйте общий htmlspecialchars
или более точный инструмент, например HTML очиститель.
Чтобы обратиться к редактированию: единственным другим слоем, который вы могли бы добавить, является валидация данных, например. подтвердите, что если вы помещаете целое число в базу данных и ожидаете положительного целого числа, вы возвращаете пользователю ошибку при попытке ввести отрицательное целое число. Что касается целостности данных, mysql_real_escape_string
лучше всего подходит для экранирования (хотя, опять же, подготовленные операторы - это более чистая система, которая позволяет избежать полного экранирования).
Ответ 5
mysql_real_escape_string()
полезен только для предотвращения атак SQL-инъекций. Это не поможет вам предотвратить атаки на сценарии межсайтового сценария. Для этого вы должны использовать htmlspecialchars()
непосредственно перед выводом данных, которые были первоначально собраны с пользовательского ввода.
Ответ 6
Существует два способа: использовать подготовленные инструкции (как упоминалось в других ответах), но это замедлит ваше приложение, потому что теперь вам нужно отправить два запроса в базу данных, а не в одну. Если вы можете жить с пониженной производительностью, то идите на это; Подготовленные заявления делают ваш код более красивым и понятным.
Если вы решили использовать mysql_real_escape_string, убедитесь, что вы избегаете всех ненадежных строк. Сохраненная строка (mysql_real_escape_string) - это безопасная SQL-инъекция. Если вы не избежите всех строк, тогда вы не защищены. Вы действительно должны объединить mysql_real_escape_string с проверкой ввода; проверяя, что переменная, которую вы ожидаете провести на самом деле, представляет собой число и в пределах ожидаемого диапазона. Помните, никогда не доверяйте пользователю.
Ответ 7
Существуют различные типы "очистки".
mysql_real_escape_string достаточно для данных базы данных, но все равно будет оцениваться браузером при отображении, если это HTML.
Чтобы удалить HTML с пользовательского ввода, вы можете использовать strip_tags.
Я бы предложил вам использовать PDO вместо обычного материала MySQL, поскольку он поддерживает подготовленные операторы прямо из коробки, и те, которые обрабатывают утечку недействительных данных для вас.
Ответ 8
Вы можете попробовать оба, как в
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)));
}
Ответ 9
Лучшим способом было бы использовать Подготовленные отчеты
Ответ 10
Я думал, что добавлю, что PHP 5.2+ имеет функции входных фильтров, которые могут дезинформировать пользовательский ввод различными способами.
Здесь ручная запись, а также сообщение в блоге [Matt Butcher] о том, почему они великолепны.