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

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

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

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

<script

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

Ответ 1

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

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

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

Ответ 2

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

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

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

Короче:

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

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

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

Ответ 3

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

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

Ответ 4

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

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

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

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

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

Подробнее см. http://ha.ckers.org/xss.html

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

Ответ 5

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

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

См. статью Джоэля о Сделать код Look Wrong для справки с этим

Ответ 6

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

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

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

Ответ 7

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

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

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

Ответ 8

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

Ответ 9

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

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

Ответ 10

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

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

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

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

Ответ 11

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

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

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

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

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

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

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

Ответ 12

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

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

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

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

Ответ 13

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

Ответ 14

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

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

Ответ 15

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

Ответ 16

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

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

Ответ 17

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

Ответ 18

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

Ответ 19

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

Ответ 20

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

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