Как мне кодировать HTML весь вывод в веб-приложении?

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

  •  09-06-2019
  •  | 
  •  

Вопрос

Я хочу предотвратить XSS-атаки в своем веб-приложении.Я обнаружил, что HTML-кодирование вывода действительно может предотвратить XSS-атаки.Теперь проблема в том, как мне закодировать HTML каждый вывод в моем приложении?У меня есть способ автоматизировать это?

Я ценю ответы для JSP, ASP.net и PHP.

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

Решение

Вы не хотите кодировать весь HTML, вы хотите кодировать только любой пользовательский ввод, который вы выводите.

Для PHP: HTMLentities и htmlспециальные символы

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

Одна вещь, которую ты не должен do — фильтровать входные данные по мере их поступления.Люди часто предлагают это, поскольку это самое простое решение, но оно приводит к проблемам.

Входные данные могут быть отправлены в несколько мест, а также выведены в формате HTML.Например, он может храниться в базе данных.Правила фильтрации данных, отправляемых в базу данных, сильно отличаются от правил фильтрации вывода HTML.Если вы кодируете HTML все входные данные, в вашей базе данных останется HTML.(Именно поэтому функция «волшебных кавычек» PHP — плохая идея.)

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

Это дополнительная работа, но ее можно сократить, используя механизмы шаблонов или библиотеки.

В случае JSP вы можете получить свой пирог и съесть его с помощью тега c:out, который по умолчанию экранирует XML.Это означает, что вы можете привязываться к своим свойствам как к необработанным элементам:

<input name="someName.someProperty" value="<c:out value='${someName.someProperty}' />" />

При привязке к строке someName.someProperty будет содержать входные данные XML, но при выводе на страницу они будут автоматически экранированы для предоставления объектов XML.Это особенно полезно для ссылок для проверки страницы.

Хороший способ избежать всего пользовательского ввода — написать модификатор для smarty, который экранирует все переменные, передаваемые в шаблон;за исключением тех, к которым прикреплен |unescape.Таким образом, вы предоставляете доступ HTML только к тем элементам, к которым вы явно предоставляете доступ.

У меня больше нет этого модификатора;но примерно такую ​​же версию можно найти здесь:

http://www.madcat.nl/martijn/archives/16-Using-smarty-to-prevent-HTML-injection..html

В новой версии Django 1.0 это работает точно так же, сойка :)

Мое личное предпочтение — старательно кодировать что-либо это исходит из базы данных, бизнес-уровня или от пользователя.

В ASP.Net это делается с помощью Server.HtmlEncode(string) .

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

Вы можете обернуть echo/print и т.д.в ваших собственных методах, которые затем можно использовать для экранирования вывода.то естьвместо

echo "blah";

использовать

myecho('blah');

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

В одном проекте у нас был режим отладки в наших функциях вывода, который делал весь выводимый текст, проходящий через наш метод, невидимым.Тогда мы знали, что все, что осталось на экране, НЕ было скрыто!Было очень полезно отследить эти непослушные неэкранированные фрагменты :)

Если вы на самом деле кодируете каждый вывод в формате HTML, пользователь увидит простой текст <html>.вместо работающего веб-приложения.

РЕДАКТИРОВАТЬ:Если вы кодируете каждый ввод в формате HTML, у вас возникнут проблемы с принятием внешнего пароля, содержащего < и т. д.

Единственный способ по-настоящему защитить себя от такого рода атак — это тщательно фильтровать все принимаемые вами входные данные, особенно (хотя и не исключительно) из общедоступных областей вашего приложения.Я бы порекомендовал вам взглянуть на Дэниела Морриса. Класс фильтрации PHP (полное решение), а также Zend_Filter пакет (набор классов, которые вы можете использовать для создания собственного фильтра).

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

Киран.

OWASP имеет хороший API для кодирования вывода HTML, либо для использования в качестве текста HTML (например,абзац или <textarea> контент) или как значение атрибута (например,для <input> теги после отклонения формы):

encodeForHTML($input) // Encode data for use in HTML using HTML entity encoding
encodeForHTMLAttribute($input) // Encode data for use in HTML attributes.

Проект (версия PHP) размещен под http://code.google.com/p/owasp-esapi-php/ а также доступно для некоторых других языков, например..СЕТЬ.

Помните, что вам следует кодировать все (не только пользовательский ввод), и как можно позже (не при хранении в БД, а при выводе HTTP-ответа).

Кодирование вывода, безусловно, является лучшей защитой.Проверка введенных данных полезна по многим причинам, но не является 100% защитой.Если база данных заражается XSS посредством атаки (т.е.ASPROX), ошибка или проверка ввода злонамеренности ничего не дает.Кодирование вывода по-прежнему будет работать.

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

Var dsFirstName, uhsFirstName : String;

Begin

uhsFirstName := request.queryfields.value['firstname'];

dsFirstName := dsHtmlToDB(uhsFirstName);

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

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