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

У меня PHP настроен так, что магические кавычки включены, и регистрация глобальных переменных отключена.

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

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

<script 

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

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

Мой подход к безопасности ввода / вывода:

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

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

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

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

Короче говоря:

  1. Вы не знаете, куда ваши данные идут
  2. На самом деле данные могут оказаться в нескольких местах, требующих использования механизма выхода из строя, НО НЕ ОБА
  3. Данные, сбежавшие за неправильную цель, действительно не очень приятны. (Например, получите электронное письмо с темой «Перейти в панель Tommy»).)

Esp # 3 будет возникать, если вы избежите данных на уровне ввода (или вам нужно снова убрать его и т. Д.).

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

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

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

Это большой вопрос.

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

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

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

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

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

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

rikh Записывает:

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

См. Статью Джоэла о том, как правильно выглядеть в кодексе.

Для этого я полагаюсь на PHPTAL .

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

«Зарегистрировать глобальные переменные», хотя отключение это определенно хорошая идея, имеет дело с проблемой, совершенно отличной от XSS.

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

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

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

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

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

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

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

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

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

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