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

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

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
6
0
7 382
11
Перейти к ответу Данный вопрос помечен как решенный

Ответы 11

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

Обновлено: если вы кодируете HTML каждый ввод, у вас возникнут проблемы с принятием внешнего пароля, содержащего <и т. д.

Все с точки зрения ASP.NET или PHP - это просто строка в буфере ответа.

Eugene Yokota 12.09.2008 15:35

Вы не кодируете ввод перед его обработкой. Вы кодируете ввод, когда выводите его пользователю ... так работают XSS-атаки.

David McLaughlin 12.09.2008 15:42
Ответ принят как подходящий

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

Для PHP: htmlentities и htmlspecialchars

Фактически, вы должны кодировать весь текст внутри тега или атрибута HTML - независимо от того, исходил ли он от пользователя. Например: <a title = "Barnes &amp; Noble&apos;s Books">Barnes &amp; Noble&apos;s Books</a>

JW. 04.03.2011 19:12

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

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

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

В новом выпуске Django 1.0 это работает точно так же, Джей :)

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

echo "blah";

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

myecho('blah');

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

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

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

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

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

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

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

Киран.

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

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

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

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

Только при санации html-тегов вы не учли SQL-инъекцию.

dotslashlu 19.09.2011 21:06

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

JW. 19.09.2011 21:21

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

Var dsFirstName, uhsFirstName : String;

Begin

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

dsFirstName := dsHtmlToDB(uhsFirstName);

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

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

MetroidFan2002 16.09.2008 06:51

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

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

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

К сожалению, c:out недостаточно для атрибутов html :-(

Peter Štibraný 25.10.2012 13:07

@ PeterŠtibraný Не могли бы вы развить свою точку зрения? Было бы хорошо понять, почему c:out не рекомендуется для экранирования атрибутов HTML.

Jimadine 22.12.2018 19:32

@Jimadine: в то время как c: out избегает одинарных и двойных кавычек, Internet Explorer также поддерживает обратные кавычки (`) в качестве разделителей атрибутов, и поэтому их также необходимо экранировать. Об этом есть забавная статья на wonko.com/post/html-escaping

Peter Štibraný 26.01.2019 00:55

@ PeterŠtibraný Интересно, я этого не знал. Спасибо за информацию.

Jimadine 28.01.2019 12:22

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

У 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).

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