Как мне HTML кодировать весь вывод в веб-приложении? - PullRequest
6 голосов
/ 12 сентября 2008

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

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

Ответы [ 11 ]

9 голосов
/ 13 сентября 2008

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

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

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

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

4 голосов
/ 12 сентября 2008

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

Для PHP: htmlentities и htmlspecialchars

3 голосов
/ 16 сентября 2008

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

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

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

1 голос
/ 12 сентября 2008

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

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

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

1 голос
/ 12 сентября 2008

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

echo "blah";

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

myecho('blah');

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

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

1 голос
/ 12 сентября 2008

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

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

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

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

0 голосов
/ 16 января 2012

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/ и также доступен для некоторых других языков, например. .NET.

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

0 голосов
/ 01 февраля 2011

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

0 голосов
/ 13 сентября 2008

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

Var dsFirstName, uhsFirstName : String;

Begin

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

dsFirstName := dsHtmlToDB(uhsFirstName);

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

0 голосов
/ 12 сентября 2008

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

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

Киран.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...