XSS – Какие HTML-теги и атрибуты могут вызывать события Javascript?

Я пытаюсь закодировать безопасный и легкий белый-основанный на основе HTML очиститель, который будет использовать DOMDocument. Чтобы избежать ненужной сложности, я готов сделать следующие компромиссы:

  • HTML-комментарии удалены
  • теги script и style разделяются вместе
  • будут возвращены только дочерние узлы тега body
  • все атрибуты HTML, которые могут запускать события Javascript, будут либо проверены, либо удалены

Я много читал об атаках и предотвращении XSS, и я надеюсь, что я не слишком наивна (если да, то сообщите мне!) В предположении, что если я последую всем правилам, упомянутым выше, я буду безопасно от XSS.

Проблема в том, что я не уверен, что другие теги и атрибуты (в любой версии [X] HTML и / или версии / реализации браузера) могут инициировать события Javascript, помимо атрибутов события Javascript по умолчанию :

  • onAbort
  • onBlur
  • onChange
  • onClick
  • onDblClick
  • onDragDrop
  • onError
  • onFocus
  • onKeyDown
  • onKeyPress
  • onKeyUp
  • onLoad
  • onMouseDown
  • onMouseMove
  • onMouseOut
  • onMouseOver
  • onMouseUp
  • onMove
  • onReset
  • onResize
  • onSelect
  • onSubmit
  • onUnload

Существуют ли какие-либо другие атрибуты событий, не относящиеся к умолчанию или запатентованные, которые могут запускать события Javascript (или VBScript и т. Д.) Или выполнение кода? Я могу думать о href , style и action , например:

 <a href="javascript:alert(document.location);">XSS</a> // or <b style="width: expression(alert(document.location));">XSS</b> // or <form action="javascript:alert(document.location);"><input type="submit" /></form> 

Я, вероятно, просто удалю любые атрибуты style в тегах HTML, атрибуты action и href представляют собой большую проблему, но я думаю, что следующий код достаточно, чтобы убедиться, что их значение является относительным или абсолютным URL-адресом, а не каким-то неприятным кодом Javascript:

 $value = $attribute->value; if ((strpos($value, ':') !== false) && (preg_match('~^(?:(?:s?f|ht)tps?|mailto):~i', $value) == 0)) { $node->removeAttributeNode($attribute); } 

Итак, мои два очевидных вопроса:

  1. Не хватает ли каких-либо тегов или атрибутов, которые могут вызывать события?
  2. Есть ли какой-либо вектор атаки, который не распространяется на эти правила?

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

Спасибо, я благодарен всем вашим ценным ответам.

Вы href и action как места javascript: могут появляться URL-адреса, но вы не src атрибут src среди множества других атрибутов загрузки URL-адреса.

Строка 399 OWASP Java HTMLPolicyBuilder – это определение атрибутов URL в дезинфицирующем средстве HTML с белым листингом.

 private static final Set<String> URL_ATTRIBUTE_NAMES = ImmutableSet.of( "action", "archive", "background", "cite", "classid", "codebase", "data", "dsync", "formaction", "href", "icon", "longdesc", "manifest", "poster", "profile", "src", "usemap"); 

Индекс HTML5 содержит сводку типов атрибутов. Он не упоминает некоторые условные вещи, такие как <input type=URL value=...> но если вы просматриваете этот список для действительного URL-адреса и друзей, вы должны получить приличное представление о том, что добавляет HTML5. Набор атрибутов HTML 4 с типом %URI также информативен.

Белый список ваших протоколов очень похож на дезинфицирующее средство OWASP . Добавление ftp и sftp выглядит достаточно безобидным.

Хорошим источником информации о схеме, связанной с безопасностью для элемента HTML и атрибутов, являются белые списки Caja JSON, которые используются дезинфицирующим средством Caja JS HTML .

Как вы планируете рендерить итоговую DOM? Если вы не будете осторожны, то даже если вы удалите все элементы <script> , злоумышленник может получить багги-рендерер для создания контента, который браузер интерпретирует как содержащий элемент <script> . Рассмотрим допустимый HTML, который не содержит элемент сценария.

 <textarea><&#47;textarea><script>alert(1337)</script></textarea> 

Багги-рендерер может выводить содержимое этого как:

 <textarea></textarea><script>alert(1337)</script></textarea> 

который содержит элемент сценария.

(Полное раскрытие: я написал фрагменты обоих дезинфицирующих средств HTML, упомянутых выше).

Гаруда уже дал то, что я считаю «правильным», и его ссылки очень полезны, но он избил меня до удара!

Я даю свой ответ только для усиления.

В этот день и возраст возрастающих функций в спецификациях html и ecmascript, избегая инъекции скриптов и других подобных уязвимостей в html становится все труднее. С каждым новым дополнением вводится целый мир возможных инъекций. Это связано с тем, что у разных браузеров, вероятно, есть разные идеи о том, как они собираются реализовать эти спецификации, поэтому вы получаете еще более возможные уязвимости.

Взгляните на короткий список векторов, введенный html 5

Лучшее решение – выбрать то, что вы позволите, а не то, что вы отрицаете. Гораздо проще сказать: «Эти теги и эти атрибуты только для тех, которые указаны в тегах, разрешены. Все остальное будет дезинфицировано соответствующим образом или выброшено».

Для меня было бы очень безответственно составить список и сказать «хорошо, вот вам: вот список всех вложенных векторов, которые вы пропустили. Вы можете спать спокойно». На самом деле, вероятно, существует множество инъекционных векторов, которые даже не известны черными шляпами или белыми шляпами. Как говорится на веб-сайте ha.ckers, инъекция скрипта действительно ограничена только умом.

Я хотел бы ответить на ваш конкретный вопрос, по крайней мере, немного, так что вот некоторые вопиющие упущения из вашего черного списка:

  • img src . Я думаю, что важно отметить, что src является допустимым атрибутом для других элементов и может быть потенциально опасным. img также dynsrc и lowsrc , может быть, даже больше.
  • type и атрибуты language
  • CDATA в дополнение к просто комментариям html.
  • Неправильно дезинфицированные входные значения. Это не может быть проблемой в зависимости от того, насколько строго выполняется ваш синтаксический анализ html.
  • Любые неоднозначные специальные символы. На мой взгляд, даже однозначные, вероятно, должны быть закодированы.
  • Отсутствующие или неверные котировки атрибутов (например, серьезные цитаты).
  • Преждевременное закрытие тегов textarea.
  • UTF-8 (и 7) закодированные символы в сценариях
  • Несмотря на то, что вы вернете только дочерние узлы тега тела, многие браузеры по-прежнему будут оценивать head и html элементы внутри body , а большинство элементов head only внутри body любом случае, поэтому это, вероятно, мало поможет.
  • Помимо выражений css, выражений фонового изображения
  • frame s и iframe s
  • embed и, вероятно, object и applet
  • На стороне сервера
  • Теги PHP
  • Любые другие инъекции (SQL Injection, исполняемая инъекция и т. Д.)

Кстати, я уверен, что это не имеет значения, но атрибуты camelCased недействительны xhtml и должны быть ниже. Я уверен, что это не повлияет на вас.

Вы можете проверить эти 2 ссылки для дополнительной справки:

http://adamcecc.blogspot.com/2011/01/javascript.html (это применимо только в том случае, если вы «отфильтрованный» вход всегда будет находиться между тегами сценария на странице)

http://ha.ckers.org/xss.html (в котором перечислены триггеры событий, специфичных для браузера)

Я использую HTML Purifier, как вы это делаете, по этой причине тоже в сочетании с wysiwyg-редактором. То, что я делал иначе, использует очень строгий белый список с несколькими основными метками разметки и атрибутами, доступными и расширяющими его, когда возникла необходимость. Это мешает вам атаковать очень неясные векторы (например, первое звено выше), и вы можете копаться в новом теге / атрибуте по одному.

Просто мои 2 цента.

Не забывайте обработчики событий HTML5 JavaScript

http://www.w3schools.com/html5/html5_ref_eventattributes.asp