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 ()
полезен только для предотвращения атак SQL-инъекций. Это не поможет вам предотвратить атаки с использованием межсайтовых сценариев. Для этого вы должны использовать htmlspecialchars ()
непосредственно перед выводом данных, которые изначально были собраны из пользовательского ввода.
Какие ситуации?
Для запросов SQL это прекрасно. (Подготовленные операторы лучше - я голосую за PDO , но функция ускользает просто отлично.) Для HTML и т.п. это не инструмент для работы - попробуйте общий htmlspecialchars
или более точный инструмент, например HTML Purifier .
Чтобы обратиться к редактированию : Единственный другой слой, который вы могли бы добавить, это проверка данных, например подтвердите, что если вы помещаете целое число в базу данных и ожидаете положительное целое число, вы возвращаете пользователю ошибку при попытке ввести отрицательное целое число. Что касается целостности данных, mysql_real_escape_string
- лучшее, что у вас есть для экранирования (хотя, опять же, подготовленные операторы - это более чистая система, которая полностью избегает экранирования).
Есть два способа: один - использовать подготовленные операторы (как упоминалось в других ответах), но это замедлит работу вашего приложения, потому что теперь вам нужно отправить два запроса в базу данных вместо одного. Если вы можете жить с пониженной производительностью, то дерзайте; Подготовленные операторы делают ваш код красивее и с ним легче работать.
Если вы решили использовать mysql_real_escape_string, убедитесь, что вы избегаете всех ненадежных строк. Экранированная строка (mysql_real_escape_string) является безопасной для внедрения SQL . Если вы не избежите всех ниточек, значит, вы в опасности. Вам действительно следует комбинировать mysql_real_escape_string с проверкой ввода; проверка того, что переменная, которую вы ожидаете содержать число, действительно является числом и находится в ожидаемом диапазоне. Помните, никогда не доверяйте пользователю.
Ответ на ваш вопрос: нет. Mysql_real_escape_string () подходит не для всех пользователей input и mysql_real_escape_string () не останавливают все SQL-инъекции. addlashes () - еще одна популярная функция для использования в 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)
Патч заключается в использовании кавычек вокруг идентификатора:
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 .
Существуют разные типы «очистки».
mysql_real_escape_string достаточно для данных базы данных, но все равно будет оцениваться браузером при отображении, если это HTML.
Чтобы удалить HTML из пользовательского ввода, вы можете использовать strip_tags .
Я бы посоветовал вам изучить возможность использования PDO вместо обычных материалов MySQL, поскольку он поддерживает заранее подготовленные операторы, и они обрабатывают экранирование неверных данных за вас.
К базе данных, да. Вы также захотите адекватно рассмотреть возможность экранирования / кодирования данных для вывода.
Вам также следует подумать о проверке входных данных на соответствие вашим ожиданиям.
Рассматривали ли вы использование подготовленных операторов ? PHP предлагает множество способов взаимодействия с вашей базой данных. Большинство из них лучше, чем функции mysql_ *.
PDO , MDB2 и MySQL Improved должны помочь вам начать работу.
Я подумал, что добавлю, что PHP 5.2+ имеет функции входного фильтра, которые могут дезинфицировать ввод пользователя различными способами.
Вот запись вручную , а также запись в блоге [Мэтта Батчера] о том, почему они такие замечательные.