Htmlentities против addslashes против mysqli_real_escape_string
-
19-09-2019 - |
Вопрос
Я немного почитал о защите PHP-приложений, и мне кажется, что mysqli_real_escape_string
правильна ли функция для использования при вставке данных в таблицы MySQL, потому что addslashes
может привести к некоторым странным вещам для умного злоумышленника.Верно?
Однако есть одна вещь, которая меня сбивает с толку.Кажется, я помню, как мне советовали addslashes
это лучше, чем htmlentities
при повторном воспроизведении введенных пользователем данных пользователям для защиты их данных, но кажется, что addslashes
это тот, у кого есть уязвимость.Это правда, или я неправильно помню?
Решение
Существуют различные контексты для ваших данных.Контекст вставки данных в базу данных должен экранироваться иначе, чем контекст отображения html / xml или даже сообщения электронной почты.
Экранирование данных, поступающих в базу данных, должно устареть во всем новом коде в пользу подготовленных инструкций.Любой, кто говорит вам обратное, оказывает вам большую медвежью услугу.
Экранирование данных, поступающих в браузер, должно быть экранировано несколькими различными способами в зависимости от цели.Иногда достаточно htmlspecialchars, иногда вам нужно использовать htmlentities.Иногда вам нужны числовые объекты.Это тема, по которой вам следует провести некоторое исследование, чтобы знать все нюансы.
Общее правило, по которому я живу, - проверять (не фильтровать, отклонять, если неверно) ввод и экранировать вывод (в зависимости от контекста).
Другие советы
Это разные инструменты для разных целей.
mysqli_real_escape_string делает данные безопасными для вставки в MySQL (но параметризованные запросы лучше).
Htmlentities делает данные безопасными для вывода в HTML-документ
addslashes делает данные безопасными для нескольких других ситуаций, но этого недостаточно для MySQL
Вы также могли бы использовать Библиотеки PDO который выполняет большую часть экранирования за вас, в случае, если вы можете использовать PHP5 на серверах.
Отвечая эхом, я бы лично предпочел htmlspecialchars, но кто-то может меня поправить
да, используйте mysqli_real_escape_string или библиотеку, подобную PDO, для всего пользовательского ввода.При повторном воспроизведении я использую htmlentities с ENT_QUOTES в качестве второго параметра, поскольку он экранирует все применимые символы для их html-объектов, включая кавычки.
Примечание:Следует избегать использования htmlentities() в документе, закодированном в формате UTF-8.Видишь:
Обратите внимание на (цитируется из phpwact.org):
С современными веб-браузерами и широко распространенными поддержка UTF-8 вам не нужна htmlзначения, потому что все эти символы могут быть представлены напрямую в UTF-8.Что еще более важно, в как правило, только браузеры поддерживают HTML-кодировку специальные символы - обычный текст редактор, например, не знает о HTML-объектах.В зависимости от того, что вы делаете, использование htmlentities может снизить способность других систем “потреблять” ваш контент.
Также (не подтверждено, но звучит разумно - из комментария анона здесь), символьные сущности (такие, как »или —) не работают, когда документ подается как application/xml + xhtml (если вы их не определили ).Вы все еще можете уйти от ответственности однако, используя числовую форму.
Другим интересным решением для PHP 5.2 и выше является использование расширения filter: http://www.php.net/manual/en/book .filter.php
Это позволяет вам проверять и очищать вводимые пользователем данные.Доступно множество встроенных фильтров, и их можно комбинировать с флагами, чтобы настроить их поведение.Кроме того, эти фильтры также можно использовать для проверки / очистки целых чисел, значений с плавающей точкой, электронных писем, определенных регулярных выражений.
Лично я начал использовать их в своих проектах для проверки форм и вывода введенных пользователем данных, и я очень рад, что сделал это.Хотя, когда я вставляю значения в базу данных MySQL, я использую подготовленные запросы для дополнительной безопасности.Эти решения вместе могут помочь избежать большинства SQL-инъекций и атак типа XSS.
Вы не можете иметь одну функцию "escape" и ожидать, что она будет работать все время.Существуют различные атаки, которые требуют определенных санитарных процедур.Единственный способ понять эту концепцию - написать какой-нибудь уязвимый код и затем использовать его.Написание кода эксплойта жизненно важно для понимания любой системы безопасности.
Например, этот запрос уязвим для Sql-инъекции:
$host=htmlspecialchars($_GET[host],ENT_QUOTES);
$name=htmlspecialchars($_GET[name],ENT_QUOTES);
mysql_query("select * from user where Host='$host' and Name='$name' ");
Эксплуатировать:http://localhost/sqli_test.php?host =\&name=%20sleep(20)--%201
Лучшая функция escape для mysql - mysqli_real_escape_string(), но это может привести к сбою:
mysql_query("select * from user where id=".mysqli_real_escape_string($_GET[id]));
эксплуатировать:http://localhost/sqli_test.php?id=1%20or%20sleep (20)
На самом деле лучший способ позаботиться о sql-инъекции - это не вызывать escape-функцию, а использовать параметризованные запросы ADODB для sql-инъекции.Используйте htmlspecialcahrs($var,ENT_QUTOES) для XSS.Прочтите OWASP топ - 10 потому что существует гораздо больше проблем, чем может пойти не так с безопасностью веб-приложений.