Меня не беспокоят другие виды атак. Просто хочу знать, может ли HTML Encode предотвратить все виды XSS-атак.
Есть ли способ провести атаку XSS, даже если используется кодирование HTML?

Я так не верю. Html Encode преобразует все функциональные символы (символы, которые могут быть интерпретированы браузером как код) в ссылки на сущности, которые не могут быть проанализированы браузером и, следовательно, не могут быть выполнены.
<script/>
Вышеуказанное не может быть выполнено браузером.
** Если, конечно, это не ошибка в браузере. *
Если кодировать все, то получится. (в зависимости от вашей платформы и реализации htmlencode) Но любое полезное веб-приложение настолько сложно, что легко забыть проверить каждую его часть. Или, может быть, сторонний компонент небезопасен. Или, может быть, какой-то путь кода, который вы кодировали, не сделал этого, поэтому вы забыли его в другом месте.
Так что вы, возможно, захотите проверить и на стороне ввода. И вы можете проверить то, что вы читаете из базы данных.
Если вы систематически кодируете весь пользовательский ввод перед отображением тогда да, ты в безопасности, вы все равно не на 100% безопасны.
(Подробнее см. Сообщение @ Avid)
Кроме того, возникают проблемы, когда вам нужно позволить тегам немного оставаться незакодированными, чтобы вы разрешили пользователям публиковать изображения или полужирный текст или любую функцию, которая требует, чтобы пользовательский ввод обрабатывался как (или преобразовывался в) некодированную разметку.
Вам нужно будет настроить систему принятия решений, чтобы решить, какие теги разрешены, а какие нет, и всегда возможно, что кто-то найдет способ пропустить запрещенный тег.
Это помогает, если вы следуете совету Джоэла о Сделать неправильный код неправильным или если твой язык помогает тебе, предупреждая / не компилируя, когда вы выводите необработанные данные пользователя (статическая типизация).
Хотя здесь есть и хороший момент относительно обхода некоторых тегов, ответ на вопрос неверен. Смотрите мой ответ ...
Добавил комментарий к OP, поэтому вместо этого он принимает ваш ответ. И добавил ссылку в своем посте на свой ответ, на всякий случай.
Как уже упоминалось всеми, вы в безопасности, пока кодируете ввод пользователя все перед его отображением. Сюда входят все параметры запроса и данные, полученные из базы данных, которые могут быть изменены пользователем.
В качестве упомянутый Пат вам иногда нужно отображать некоторые теги, но не все теги. Один из распространенных способов сделать это - использовать язык разметки, такой как Текстиль, Уценка или BBCode. Однако имейте в виду, что даже языки разметки могут быть уязвимы для XSS.
# Markup example
[foo](javascript:alert\('bar'\);)
Если вы все же решите пропустить "безопасные" теги, я бы порекомендовал найти какую-нибудь существующую библиотеку для синтаксического анализа и дезинфекции вашего кода перед выводом. Есть много XSS векторов, которые вам нужно будет обнаружить, прежде чем ваше дезинфицирующее средство станет достаточно безопасным.
Я второй совет Metavida найти стороннюю библиотеку для обработки выходной фильтрации. Нейтрализация символов HTML - хороший способ остановить атаки XSS. Однако код, который вы используете для преобразования метасимволов, может быть уязвим для атак с уклонением; например, если он неправильно обрабатывает Unicode и интернационализацию.
Классическая простая ошибка выходных фильтров homebrew заключается в том, что они улавливают только <и>, но пропускают такие вещи, как ", что может разбить управляемый пользователем вывод в пространство атрибутов тега HTML, где Javascript может быть прикреплен к DOM.
Нет.
Не говоря уже о разрешении некоторых тегов (а не о сути вопроса), HtmlEncode просто НЕ покрывает все атаки XSS.
Например, рассмотрим сгенерированный сервером javascript на стороне клиента - сервер динамически выводит значения в кодировке htmlencoded непосредственно в javascript на стороне клиента, htmlencode прерывает выполнение сценария не останавливаться.
Далее рассмотрим следующий псевдокод:
<input value=<%= HtmlEncode(somevar) %> id=textbox>
Теперь, если это не сразу очевидно, если somevar (отправленный пользователем, конечно) установлен, например, на
a onclick=alert(document.cookie)
результирующий результат
<input value=a onclick=alert(document.cookie) id=textbox>
что явно сработает. Очевидно, это может быть (почти) любой другой скрипт ... и HtmlEncode не сильно поможет.
Есть несколько дополнительных векторов, которые следует учитывать ... включая третий вариант XSS, называемый XSS на основе DOM (в котором вредоносный сценарий генерируется динамически на клиенте, например, на основе значений #).
Также не забываем про атаки типа UTF-7 - где атака выглядит как
+ADw-script+AD4-alert(document.cookie)+ADw-/script+AD4-
Там особо нечего кодировать ...
Решение, конечно (в дополнение к правильной и ограничительной проверке ввода белого списка), заключается в выполнении кодирования контекстно-зависимый: HtmlEncoding отлично подходит, ЕСЛИ вы выводите контекст - это HTML, или, может быть, вам нужно JavaScriptEncoding, или VBScriptEncoding, или AttributeValueEncoding, или ... так далее.
Если вы используете MS ASP.NET, вы можете использовать их библиотеку Anti-XSS, которая предоставляет все необходимые методы контекстного кодирования.
Обратите внимание, что вся кодировка не должна ограничиваться вводом пользователя, но также должна сохраняться значения из базы данных, текстовых файлов и т. д.
О, и не забудьте явно установить кодировку, как в заголовке HTTP, так и в теге META, иначе у вас все равно будут уязвимости UTF-7 ...
Дополнительную информацию и довольно подробный список (постоянно обновляемый) см. В шпаргалке RSnake: http://ha.ckers.org/xss.html
Конечно, изначально неправильно писать <input value = <% = HtmlEncode (somevar)%> id = textbox>, а не <input value = "<% = HtmlEncode (somevar)"%> id = textbox>, если вы не знаете, содержит ли текст, например, пустой.
В том-то и дело - HTMLEncode не защищает от ошибок. Конечно, программист ожидал, что somevar будет содержать 23 - это как раз тот мерзкий злоумышленник, который решил засунуть пробел в ...
Не помогло бы заключить его, image, что SOMEVAR включает этот текст | "onclick =" alert (); "" | затем он будет отображаться как действительный тег.
Espo - Я опаздываю в этом вопросе - но это, безусловно, помогает заключить и закодировать - как в вашем примере, htmlencoding это (цитата) даст: & quot; и таким образом будет onclick = & quot; alert ()
@Adam, правильным решением здесь является кодирование атрибута it (в дополнение к его включению) вместо html-encode. Контекст другой, поэтому правила кодирования тоже разные - кодировка html здесь вам не поможет.
@AviD Учитывая функцию HtmlEncode (), которая делает кодирует символы кавычек (как код ASP в примере), можете ли вы предоставить пример значения XSS для <input value = "<%= HtmlEncode(value) %>" id=textbox>?
Я хотел бы предложить очиститель HTML (http://htmlpurifier.org/). Он не просто фильтрует html, он в основном токенизирует и повторно компилирует его. Это действительно индустриальная сила.
У него есть дополнительное преимущество, позволяющее гарантировать корректный вывод html / xhtml.
Также n'thing Textile, это отличный инструмент, и я использую его все время, но я бы запустил его и через очиститель HTML.
Я не думаю, что вы поняли, что я имел в виду re tokens. Очиститель HTML не просто «фильтрует», он фактически реконструирует HTML. http://htmlpurifier.org/comparison.html
Нет, простое кодирование обычных HTML-токенов НЕ полностью защищает ваш сайт от XSS-атак. См., Например, эту XSS-уязвимость, обнаруженную в google.com:
http://www.securiteam.com/securitynews/6Z00L0AEUE.html
Важным в этом типе уязвимости является то, что злоумышленник может кодировать свои полезные данные XSS с использованием UTF-7, и если вы не указали другую кодировку символов на своей странице, браузер пользователя может интерпретировать полезные данные UTF-7 и выполнить сценарий атаки.
Еще одна вещь, которую вам нужно проверить, - это откуда поступают ваши данные. Вы можете использовать строку реферера (в большинстве случаев), чтобы проверить, что она находится на вашей собственной странице, но ввод скрытого случайного числа или чего-то еще в вашей форме, а затем проверка его (возможно, с помощью переменной набора сеанса) также помогает понять, что ввод поступает с вашего собственного сайта, а не с какого-то фишингового сайта.
Или если Javascript каким-то образом используется для изменения пользовательского ввода для целей графического интерфейса. Я столкнулся с XSS-уязвимостью, которая сначала кодировала <> в <и> ... но при передаче этой функции они были снова заменены! Итак ... я думаю, ваша защита от XSS-атак. :)