Есть ли где-нибудь функция-ловушка, которая хорошо работает для дезинфекции пользовательского ввода для SQL-инъекций и XSS-атак, но при этом допускает определенные типы HTML-тегов?
php
security
xss
sql-injection
user-input
казарка
источник
источник
select * from users where name='$name'
, тогда не имеет значения, используете ли вы PDO, MySQLi или MySQL. Вы все еще в опасности. Вы должны использовать параметризованные запросы или, если необходимо, использовать механизмы экранирования ваших данных, но это гораздо менее предпочтительно.Ответы:
Это распространенное заблуждение, что пользовательский ввод может быть отфильтрован. В PHP даже есть (теперь устаревшая) «функция», называемая магическими кавычками , которая основывается на этой идее. Это чепуха. Забудьте о фильтрации (или очистке, или как люди это называют).
То, что вы должны сделать, чтобы избежать проблем, довольно просто: всякий раз, когда вы встраиваете строку в чужой код, вы должны избегать ее в соответствии с правилами этого языка. Например, если вы встраиваете строку в некоторый SQL, ориентированный на MySQL, вы должны экранировать строку с помощью функции MySQL для этой цели (
mysqli_real_escape_string
). (Или, в случае баз данных, использование подготовленных заявлений является лучшим подходом, когда это возможно.)Другой пример - HTML: если вы встраиваете строки в разметку HTML, вы должны экранировать их с помощью
htmlspecialchars
. Это означает , что каждыйecho
илиprint
оператор должен использоватьhtmlspecialchars
.Третьим примером могут быть команды оболочки: если вы собираетесь встраивать строки (например, аргументы) во внешние команды и вызывать их с помощью
exec
, то вы должны использоватьescapeshellcmd
иescapeshellarg
.И так далее ...
Только случай , когда вам нужно активно фильтровать данные, если вы будете принимать Преформатированный вход. Например, если вы разрешите своим пользователям публиковать разметку HTML, которую вы планируете показывать на сайте. Однако вам следует избегать этого любой ценой, поскольку независимо от того, насколько хорошо вы его фильтруете, это всегда будет потенциальной дырой в безопасности.
источник
mysql_real_escape_string
не рекомендуется. В настоящее время считается хорошей практикой использовать подготовленные операторы для предотвращения внедрения SQL. Так что переключайтесь на MySQLi или PDO.Не пытайтесь предотвратить внедрение SQL путем очистки входных данных.
Вместо этого не допускайте использования данных при создании кода SQL . Используйте подготовленные операторы (то есть, используя параметры в шаблонном запросе), которые используют связанные переменные. Это единственный способ гарантировать защиту от SQL-инъекций.
Пожалуйста, посетите мой веб-сайт http://bobby-tables.com/ для получения дополнительной информации о предотвращении внедрения SQL.
источник
Нет. Вы не можете в общем фильтровать данные без контекста того, для чего они нужны. Иногда вы хотите принять запрос SQL в качестве входных данных, а иногда вы хотите принять HTML в качестве входных данных.
Вам необходимо отфильтровать входные данные в белом списке - убедитесь, что данные соответствуют некоторой спецификации того, что вы ожидаете. Затем вам нужно избежать его, прежде чем использовать его, в зависимости от контекста, в котором вы его используете.
Процесс экранирования данных для SQL - для предотвращения внедрения SQL - очень отличается от процесса экранирования данных для (X) HTML, чтобы предотвратить XSS.
источник
В PHP появились новые приятные функции filter_input, которые, например, освобождают вас от поиска «конечного регулярного выражения электронной почты» теперь, когда есть встроенный тип FILTER_VALIDATE_EMAIL.
Мой собственный класс фильтра (использует JavaScript для выделения ошибочных полей) может быть инициирован либо запросом ajax, либо обычной формой публикации. (см. пример ниже)
Конечно, имейте в виду, что вам также нужно выполнять экранирование SQL-запросов в зависимости от того, какой тип БД вы используете (mysql_real_escape_string () бесполезен, например, для SQL-сервера). Возможно, вы захотите обработать это автоматически на соответствующем прикладном уровне, таком как ORM. Также, как уже упоминалось выше: для вывода в html используйте другие специальные функции php, такие как htmlspecialchars;)
Для того, чтобы действительно разрешить ввод HTML с разделенными классами и / или тегами, используйте один из выделенных пакетов проверки xss. НЕ ПИШИТЕ СВОИ СОБСТВЕННЫЕ РЕКЕКСЫ ДЛЯ РАЗДЕЛЕНИЯ HTML
источник
Нет, нет.
Прежде всего, SQL-инъекция - это проблема фильтрации ввода, а XSS - выход, выходящий за ее пределы, поэтому вы даже не выполняете эти две операции одновременно в жизненном цикле кода.
Основные правила большого пальца
mysql_real_escape_string()
)strip_tags()
для фильтрации нежелательного HTMLhtmlspecialchars()
и помните о 2-м и 3-м параметрах здесь.источник
Чтобы решить проблему XSS, взгляните на HTML Purifier . Это довольно настраиваемый и имеет достойный послужной список.
Что касается атак с использованием SQL-инъекций, убедитесь, что вы проверили пользовательский ввод, а затем запустили его через mysql_real_escape_string (). Однако эта функция не победит все атаки с использованием инъекций, поэтому важно проверить данные перед тем, как вывести их в строку запроса.
Лучшее решение - использовать подготовленные заявления. Библиотека PDO и расширение mysqli поддерживают их.
источник
В PHP 5.2 появилась функция filter_var .
Он поддерживает множество фильтров SANITIZE, VALIDATE.
http://php.net/manual/en/function.filter-var.php
источник
Одна хитрость, которая может помочь в определенных обстоятельствах, когда у вас есть страница, подобная которой,
/mypage?id=53
и вы используете идентификатор в предложении WHERE, это убедиться, что идентификатор определенно является целым числом, например так:Но, конечно, это исключает только одну конкретную атаку, поэтому прочитайте все остальные ответы. (И да, я знаю, что приведенный выше код не очень хорош, но он показывает конкретную защиту.)
источник
$id = (int)$_GET['id']
и$que = sprintf('SELECT ... WHERE id="%d"', $id)
тоже хорошоИспользуйте современные версии MySQL и PHP.
Установите кодировку явно:
Используйте безопасные кодировки:
Используйте пространственную функцию:
PDO :: quote () - помещает кавычки вокруг входной строки (если требуется) и экранирует специальные символы во входной строке, используя стиль цитирования, соответствующий базовому драйверу:
Подготовленные операторы PDO : против подготовленных MySQLi операторов поддерживается больше драйверов базы данных и именованных параметров:
mysql_real_escape_string[устарело в PHP 5.5.0, удалено в PHP 7.0.0].Проверьте, что переменная содержит то, что вы ожидаете:
Использовать функцию фильтра filter_var () - фильтрует переменную с указанным фильтром:
более предопределенные фильтры
источник
То, что вы описываете здесь, это две отдельные проблемы:
1) Пользовательский ввод всегда следует считать плохим.
Использование подготовленных операторов или / и фильтрация с помощью mysql_real_escape_string, безусловно, необходимо. PHP также имеет встроенный фильтр filter_input, с которого можно начать.
2) Это большая тема, и она зависит от контекста выводимых данных. Для HTML существуют такие решения, как htmlpurifier. как правило, всегда избегайте всего, что вы выводите.
Обе проблемы слишком велики, чтобы их можно было рассмотреть в одном посте, но есть много постов, которые рассматриваются более подробно:
Методы вывода PHP
Более безопасный вывод PHP
источник
Если вы используете PostgreSQL, ввод из PHP может быть экранирован с помощью pg_escape_string ()
Из документации ( http://php.net/manual/es/function.pg-escape-string.php ):
источник
Там нет функции catchall, потому что есть несколько проблем, которые необходимо решить.
SQL-инъекция. Сегодня, как правило, каждый PHP-проект должен использовать подготовленные операторы через PHP Data Objects (PDO) в качестве лучшей практики, предотвращающей ошибку из-за случайных цитат, а также полнофункциональное решение для внедрения . Это также самый гибкий и безопасный способ доступа к вашей базе данных.
Прочтите (Единственное правильное) руководство по PDO, чтобы узнать почти все, что вам нужно знать о PDO. (Искренне благодарим ведущего SO SO, @YourCommonSense, за этот замечательный ресурс по этой теме.)
XSS - очистить данные на пути в ...
HTML Purifier существует уже давно и до сих пор активно обновляется. Вы можете использовать его для дезинфекции вредоносного ввода, в то же время позволяя использовать щедрый и настраиваемый белый список тегов. Прекрасно работает со многими редакторами WYSIWYG, но может быть тяжелым для некоторых случаев использования.
В других случаях, когда мы вообще не хотим принимать HTML / Javascript, я обнаружил, что эта простая функция полезна (и прошла несколько проверок XSS):
/* Prevent XSS input */ function sanitizeXSS () { $_GET = filter_input_array(INPUT_GET, FILTER_SANITIZE_STRING); $_POST = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING); $_REQUEST = (array)$_POST + (array)$_GET + (array)$_REQUEST; }
XSS - Санитарная обработка данных при выходе ... если вы не гарантируете, что данные были должным образом очищены, прежде чем добавлять их в базу данных, вам нужно будет очистить их перед отображением для вашего пользователя, мы можем использовать эти полезные функции PHP:
echo
илиprint
для отображения предоставленных пользователем значений используйте,htmlspecialchars
если данные не были должным образом очищены безопасным и не разрешено отображать HTML.json_encode
это безопасный способ предоставления пользовательских значений из PHP в JavascriptВы вызываете команды внешней оболочки, используя
exec()
илиsystem()
функции, илиbacktick
оператору? Если это так, в дополнение к SQL-инъекции и XSS у вас может возникнуть дополнительная проблема, пользователей, запускающих вредоносные команды на вашем сервере . Вам нужно использовать,escapeshellcmd
если вы хотите экранировать всю команду ИЛИ,escapeshellarg
чтобы избежать отдельных аргументов.источник
mb_encode_numericentity
обсуждается вhtmlspecialchars
ссылке на # 3 XSSСамый простой способ избежать ошибок при очистке входных данных и экранировании данных - использовать PHP-фреймворк, такой как Symfony , Nette и т. Д., Или его часть (шаблонизатор, слой базы данных, ORM).
Шаблонный двигатель, как Twig или Latte, по умолчанию экранирование выходных данных не требуется - вам не нужно решать вручную, правильно ли вы экранировали выходные данные в зависимости от контекста (HTML или Javascript часть веб-страницы).
Framework автоматически очищает входные данные, и вы не должны использовать переменные $ _POST, $ _GET или $ _SESSION напрямую, а через такой механизм, как маршрутизация, обработка сеанса и т. Д.
А для слоя базы данных (модели) существуют платформы ORM, такие как Doctrine, или оболочки для PDO, такие как Nette Database.
Вы можете прочитать больше об этом здесь - Что такое программный каркас?
источник
Просто хочу добавить, что по теме экранирования вывода, если вы используете php DOMDocument для вывода html-кода, он автоматически выйдет в нужном контексте. Атрибут (value = "") и внутренний текст <span> не равны. Чтобы быть в безопасности от XSS, прочитайте это: Шпаргалка по профилактике OWASP XSS
источник
Вы никогда не дезинфицируете ввод.
Вы всегда дезинфицируете продукцию.
Преобразования, которые вы применяете к данным для обеспечения их безопасности для включения в оператор SQL, полностью отличаются от тех, которые вы применяете для включения в HTML, полностью отличаются от тех, которые вы применяете для включения в Javascript, и полностью отличаются от тех, которые вы применяете для включения в LDIF. полностью отличается от тех, которые вы применяете для включения в CSS, полностью отличается от тех, которые вы применяете для включения в электронную почту ....
Обязательно проверяйте ввод - решите, хотите ли вы принять его для дальнейшей обработки или скажите пользователю, что это недопустимо. Но не применяйте никаких изменений к представлению данных, пока они не покинут землю PHP.
Давным-давно кто-то пытался изобрести универсальный механизм для экранирования данных, и мы в итоге получили « magic_quotes », который неправильно экранировал данные для всех выходных целей и привел к разной установке, требующей разного кода для работы.
источник
Никогда не доверяйте пользовательским данным.
В
trim()
функции удаляет пробелы и другие предопределенные символы с обеих сторон строки.stripslashes()
Функция удаляет обратные слэшиhtmlspecialchars()
Функция преобразует некоторые предопределенные символы в HTML сущности.Предопределенные символы:
источник
clean_input
тогда? Почему вы хотите снять косые черты?Существует расширение фильтра ( howto-link , manual ), которое работает очень хорошо со всеми переменными GPC. Это не волшебство делай все, хотя, тебе все равно придется его использовать.
источник