Я хочу предотвратить атаки XSS в своем веб-приложении. Я обнаружил, что HTML Кодирование вывода может действительно предотвратить атаки XSS. Теперь проблема в том, что как HTML кодировать каждый отдельный вывод в моем приложении? У меня есть способ автоматизировать это?
Я ценю ответы на JSP, ASP.net и PHP.
Вы не хотите кодировать весь HTML, вы хотите только кодировать HTML-код любого вводимого пользователем ввода.
Для PHP: htmlentities и htmlspecialchars
Одна вещь, которую вы не должны делать, – это фильтровать входные данные по мере их появления. Люди часто предлагают это, поскольку это самое простое решение, но это приводит к проблемам.
Входные данные могут быть отправлены в несколько мест, помимо того, что они выводятся как 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 это работает точно так же, jay 🙂
Вы можете обернуть echo / print и т. Д. В своих собственных методах, которые затем можно использовать для выхода из вывода. т.е. вместо
echo "blah";
использование
myecho('blah');
у вас может быть даже второй параметр, который отключается, если вам это нужно.
В одном проекте у нас был режим отладки в наших выходных функциях, который сделал весь выходной текст, проходящий через наш метод невидимым. Тогда мы знали, что на экране ничего не осталось. Было очень полезно отслеживать эти непослушные необитаемые биты 🙂
Если вы действительно кодируете HTML каждый отдельный вывод, пользователь увидит простой текст & lt; html & gt; вместо действующего веб-приложения.
EDIT: если HTML кодирует каждый отдельный вход, у вас будет проблема с принятием внешнего пароля, содержащего <etc ..
Мое личное предпочтение состоит в том, чтобы усердно кодировать все, что поступает из базы данных, бизнес-уровня или пользователя.
В ASP.Net это делается с помощью Server.HtmlEncode(string)
.
Причина такого кодирования в том, что даже свойства, которые вы можете считать логическими или числовыми, могут содержать вредоносный код (например, значения флажка, если они выполняются неправильно, могут возвращаться как строки. Если вы не кодируете их раньше отправляя результат пользователю, тогда у вас есть уязвимость).
Единственный способ по-настоящему защитить себя от такого рода атак – это тщательно отфильтровать все входящие, которые вы принимаете, в частности (хотя и не исключительно) из публичных мест вашего приложения. Я бы порекомендовал вам взглянуть на PHP Filtering Class (полное решение) Daniel Morris, а также на пакет 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/ и также доступен для некоторых других языков, например .NET.
Помните, что вы должны кодировать все (не только пользовательский ввод) и как можно позже (не при хранении в БД, а при выводе ответа HTTP).
Кодировка вывода – безусловно лучшая защита. Подтверждение ввода отлично подходит по многим причинам, но не для защиты на 100%. Если база данных заражается XSS через атаку (т.е. ASPROX), ошибка ввода или вредоносная вставка не делает ничего. Кодировка вывода будет работать.
было хорошее эссе от Джоэла по программному обеспечению (неправильный код выглядел неправильно, я думаю, я нахожусь на своем телефоне, иначе у меня будет URL-адрес для вас), который покрывал правильное использование венгерской нотации. Короткий вариант будет примерно таким:
Var dsFirstName, uhsFirstName : String; Begin uhsFirstName := request.queryfields.value['firstname']; dsFirstName := dsHtmlToDB(uhsFirstName);
В основном префикс ваших переменных с чем-то вроде «us» для небезопасной строки «ds» для безопасной базы данных «hs» для безопасного HTML. Вы просто хотите кодировать и декодировать, где вы действительно нуждаетесь, а не все. Но, используя префиксы, которые вызывают полезное значение, глядя на ваш код, вы увидите реальную скорость, если что-то не так. И вам понадобятся разные функции кодирования / декодирования.