Каковы наилучшие методы предотвращения xss-атак на PHP-сайте

StackOverflow https://stackoverflow.com/questions/71328

  •  09-06-2019
  •  | 
  •  

Вопрос

Я настроил PHP так, что магические кавычки включены, а глобальные регистры отключены.

Я делаю все возможное, чтобы всегда вызывать htmlentities() для всего, что я выводю, что является производным от пользовательского ввода.

Я также иногда просматриваю свою базу данных на предмет общих вещей, используемых в xss, таких как...

<script

Что еще я должен делать и как я могу убедиться, что то, что я пытаюсь сделать, это всегда Выполнено.

Это было полезно?

Решение

Экранирование входных данных - не лучшее, что вы можете сделать для успешной профилактики XSS.Также выходные данные должны быть экранированы.Если вы используете механизм шаблонов Smarty, вы можете использовать |escape:'htmlall' модификатор для преобразования всех чувствительных символов в HTML-объекты (я использую собственный |e модификатор, который является псевдонимом к приведенному выше).

Мой подход к безопасности ввода / вывода заключается в следующем:

  • сохраняйте пользовательский ввод без изменений (при вводе не выполняется экранирование HTML, только экранирование с учетом базы данных, выполняемое с помощью подготовленных инструкций PDO)
  • экранирование при выводе, в зависимости от того, какой формат вывода вы используете (напримерHTML и JSON нуждаются в разных правилах экранирования)

Другие советы

Я придерживаюсь мнения, что не следует ничего экранировать во время ввода, только на выходе.Поскольку (большую часть времени) вы не можете предположить, что знаете, куда направляются эти данные.Например, если у вас есть форма, которая принимает данные, которые позже появляются в отправляемом вами электронном письме, вам нужно другое экранирование (в противном случае злоумышленник может переписать заголовки вашего электронного письма).

Другими словами, вы можете сбежать только в самый последний момент, когда данные "покидают" ваше приложение:

  • Элемент списка
  • Запись в XML-файл, экранирование для XML
  • Запись в БД, экранирование (для данной конкретной СУБД)
  • Написать электронное письмо, сбежать от электронных писем
  • и т.д.

Идти коротким путем:

  1. Вы не знаете, куда направляются ваши данные
  2. На самом деле данные могут оказаться в нескольких местах, требуя разных механизмов экранирования, НО НЕ В ОБОИХ СРАЗУ
  3. Данные, экранированные для неправильной цели, на самом деле не очень хороши.(Например.получите электронное письмо с темой "Сходите в Tommy's bar".)

Особенно # 3 произойдет, если вы экранируете данные на входном уровне (или вам нужно снова отменить экранирование и т.д.).

PS:Я поддержу совет не использовать magic_quotes, это чистое зло!

Существует множество способов сделать XSS (см. http://ha.ckers.org/xss.html) и это очень трудно поймать.

Я лично делегирую это текущему фреймворку, который я использую (например, Code Igniter).Хотя это и не идеально, но может привлечь больше внимания, чем когда-либо мои процедуры ручной работы.

Это отличный вопрос.

Во-первых, не экранируйте текст при вводе, кроме как для того, чтобы сделать его безопасным для хранения (например, для помещения в базу данных).Причина этого в том, что вы хотите сохранить то, что было введено, чтобы вы могли контекстуально представить это разными способами и в разных местах.Внесение изменений здесь может поставить под угрозу вашу последующую презентацию.

Когда вы переходите к представлению своих данных, отфильтруйте то, чего там не должно быть.Например, если нет причины для присутствия javascript, найдите его и удалите.Простой способ сделать это - использовать strip_tags_заголовки функционируйте и представляйте только те html-теги, которые вы разрешаете.

Затем возьмите то, что у вас есть, и передайте это через htmlentities или htmlspecialchars, чтобы изменить то, что там есть, на символы ascii.Делайте это, исходя из контекста и того, что вы хотите получить.

Я бы также предложил отключить Волшебные кавычки.Он был удален из PHP 6 и считается плохой практикой его использования.Подробности по адресу http://us3.php.net/magic_quotes

Для получения более подробной информации ознакомьтесь с http://ha.ckers.org/xss.html

Это не полный ответ, но, надеюсь, достаточный, чтобы помочь вам начать работу.

рих Пишет:

Я делаю все возможное, чтобы всегда вызывать htmlentities() для всего, что я выводю, что является производным от пользовательского ввода.

Смотрите эссе Джоэла о Заставляющий код Выглядеть Неправильно за помощью в этом

Я полагаюсь на ПХПТАЛ за это.

В отличие от Smarty и обычного PHP, он экранирует все выходные данные по умолчанию.Это большая победа с точки зрения безопасности, потому что ваш сайт не станет доступным для просмотра, если вы забудете htmlspecialchars() или |escape где-нибудь.

XSS - это специфичная для HTML атака, поэтому вывод HTML - это подходящее место для ее предотвращения.Вам не следует пытаться выполнять предварительную фильтрацию данных в базе данных, потому что вам может понадобиться выводить данные на другой носитель, который не принимает HTML, но имеет свои риски.

Библиотека шаблонов. Или, по крайней мере, это то, что должны делать библиотеки шаблонов.Чтобы предотвратить XSS ВСЕ выходные данные должны быть закодированы.Это не является задачей основного приложения / управляющей логики, она должна обрабатываться исключительно методами вывода.

Если вы добавите htmlentities() во весь свой код, общий дизайн будет неправильным.И, как вы предполагаете, вы можете пропустить одно или два места.Вот почему единственным решением является строгое кодирование html -> когда выходные переменные записываются в поток html / xml.

К сожалению, большинство библиотек шаблонов php добавляют только свой собственный синтаксис шаблона, но не заботятся о кодировке вывода, или локализации, или проверке html, или о чем-либо важном.Может быть, кто-то еще знает подходящую библиотеку шаблонов для php?

Для большинства сайтов достаточно избежать всего пользовательского ввода.Также убедитесь, что идентификаторы сеанса не заканчиваются в URL-адресе, чтобы их нельзя было украсть из Referer ссылка на другой сайт.Кроме того, если вы разрешаете своим пользователям отправлять ссылки, убедитесь, что они не javascript: разрешены протокольные ссылки;они будут запускать скрипт, как только пользователь нажмет на ссылку.

Если вы обеспокоены XSS-атаками, решением является кодирование ваших выходных строк в HTML.Если вы не забудете закодировать каждый отдельный выходной символ в формат HTML, то не сможете выполнить успешную XSS-атаку.

Подробнее:Очистка пользовательских данных:Как и где это сделать

Лично я бы отключил magic_quotes.В PHP5 + он отключен по умолчанию, и лучше кодировать так, как будто его там вообще нет, поскольку он не экранирует все и будет удален из PHP6.

Далее, в зависимости от того, какой тип пользовательских данных вы фильтруете, будет определяться, что делать дальше, напримересли это просто текст, напримертогда назови имя strip_tags(trim(stripslashes())); это или для проверки наличия диапазонов используйте регулярные выражения.

Если вы ожидаете определенный диапазон значений, создайте массив допустимых значений и разрешайте использовать только эти значения через (in_array($userData, array(...))).

Если вы проверяете числа, используйте is_numeric для принудительного применения целых чисел или приведения к определенному типу, это должно помешать людям пытаться отправлять строки вместо них.

Если у вас есть PHP5.2 +, то подумайте о том, чтобы посмотреть на фильтр () и использует это расширение, которое может фильтровать различные типы данных, включая адреса электронной почты.Документация не особенно хороша, но улучшается.

Если вам нужно обрабатывать HTML, то вам следует рассмотреть что-то вроде Входной фильтр PHP или Очиститель HTML.HTML Purifier также проверит HTML на соответствие.Я не уверен, что входной фильтр все еще разрабатывается.Оба варианта позволят вам определить набор тегов, которые можно использовать, и какие атрибуты разрешены.

Что бы вы ни решили, всегда помните, никогда не доверяйте ничему, что приходит в ваш PHP-скрипт от пользователя (включая вас самих!).

Все эти ответы замечательны, но, по сути, решением для XSS будет прекращение генерации HTML-документов путем манипулирования строками.

Фильтрация входных данных - это всегда хорошая идея для любого приложения.

Экранирование вашего вывода с помощью htmlentities() и friends должно работать до тех пор, пока оно используется должным образом, но это HTML-эквивалент создания SQL-запроса путем объединения строк с mysql_real_escape_string($var) - это должно сработать, но меньшее количество вещей может, так сказать, подтвердить вашу работу по сравнению с подходом, подобным использованию параметризованных запросов.

Долгосрочное решение должно заключаться в том, чтобы приложения создавали страницу внутренне, возможно, используя стандартный интерфейс, такой как DOM, а затем использовали библиотеку (например, libxml) для обработки сериализации в XHTML / HTML / etc.Конечно, нам еще далеко до того, чтобы это стало популярным и достаточно быстрым, но пока нам приходится создавать наши HTML-документы с помощью операций со строками, а это по своей сути более рискованно.

Я нахожу, что использование этой функции помогает исключить множество возможных xss-атак:http://www.codebelay.com/killxss.phps

“Волшебные кавычки” - это паллиативное средство от некоторых наихудших недостатков XSS, которое работает, экранируя все при вводе, что неправильно по замыслу.Единственный случай, когда кто-то хотел бы его использовать, - это когда вам абсолютно необходимо использовать существующее PHP-приложение, которое, как известно, написано небрежно по отношению к XSS.(В этом случае у вас серьезные проблемы даже с "волшебными кавычками”.) При разработке собственного приложения вам следует отключить ”волшебные кавычки" и вместо этого следовать методам, безопасным для XSS.

XSS, уязвимость межсайтового скриптинга, возникает, когда приложение включает строки из внешних источников (введенные пользователем, извлеченные с других веб-сайтов и т.д.) В свой [X] HTML, CSS, ECMAScript или другой анализируемый браузером вывод без надлежащего экранирования, надеясь, что специальные символы, такие как less-than (в [X] HTML), одинарные или двойные кавычки (ECMAScript), никогда не появятся.Правильное решение этой проблемы - всегда экранировать строки в соответствии с правилами языка вывода:использование сущностей в [X] HTML, обратной косой черты в ECMAScript и т.д.

Поскольку может быть трудно отслеживать то, что является ненадежным и должно быть экранировано, рекомендуется всегда экранировать все, что является “текстовой строкой”, в отличие от “текста с разметкой” на таком языке, как HTML.Некоторые среды программирования упрощают задачу, вводя несколько несовместимых типов строк:“строка” (обычный текст), “HTML-строка” (HTML-разметка) и так далее.Таким образом, прямое неявное преобразование из “string” в “HTML-строку” было бы невозможно, и единственный способ, которым строка может стать HTML-разметкой, - это передать ее через экранирующую функцию.

“Зарегистрировать глобальные файлы”, хотя отключить его, безусловно, хорошая идея, имеет дело с проблемой, полностью отличной от XSS.

Создайте для вас любые сеансовые файлы cookie (или все файлы cookie), которые вы используете HttpOnly.В этом случае большинство браузеров скроют значение файла cookie из JavaScript.Пользователь по-прежнему может вручную копировать файлы cookie, но это помогает предотвратить прямой доступ к скрипту.У StackOverflow была эта проблема во время бета-тестирования.

Это не решение, просто еще один кирпичик в стене

  • Не доверяйте вводимым пользователем данным
  • Экранирование всех выходных данных произвольного текста
  • Не используйте magic_quotes;посмотрите, есть ли вариант, специфичный для СУБД, или используйте PDO
  • Рассмотрите возможность использования файлов cookie только для HTTP, где это возможно, чтобы избежать взлома сеанса каким-либо вредоносным скриптом

Вы должны, по крайней мере, проверять все данные, поступающие в базу данных.И попробуйте также проверить все данные, покидающие базу данных.

mysql_real_escape_string хорош для предотвращения SQL-инъекции, но XSS сложнее.Вы должны использовать preg_match, stip_tags или htmlentities, где это возможно!

Лучшим текущим методом предотвращения XSS в PHP-приложении является HTML Purifier (http://htmlpurifier.org/).Одним из ее незначительных недостатков является то, что это довольно большая библиотека, и ее лучше всего использовать с кэшем операционного кода, таким как APC.Вы могли бы использовать это в любом месте, где на экран выводится ненадежный контент.Это гораздо более тщательно, чем htmlentities, htmlspecialchars, filter_input, filter_var, strip_tags и т.д.

Используйте существующую библиотеку дезинфекции пользовательского ввода для очистки ВСЕ пользовательский ввод.Если только вы не поставите лот сколько бы усилий ни прилагалось к этому, реализация этого самостоятельно никогда не будет работать так же хорошо.

Я считаю, что лучший способ - это использовать класс, который позволяет вам привязывать ваш код, чтобы вам никогда не приходилось беспокоиться о том, чтобы вручную экранировать ваши данные.

Трудно реализовать тщательную защиту от sql-инъекций / xss-инъекций на сайте, которая не вызывает ложных срабатываний.В CMS конечный пользователь может захотеть использовать <script> или <object> это ссылки на товары с другого сайта.

Я рекомендую всем пользователям установить FireFox с помощью NoScript ;-)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top