Подтвердить что ты не робот

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);
}

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

  • Я пропускаю теги или атрибуты, которые могут вызывать события?
  • Есть ли какой-либо вектор атаки, который не распространяется на эти правила?

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

Я высоко ценю все ваши ценные ответы, спасибо.

4b9b3361

Ответ 1

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

Строка 399 Java HTMLPolicyBuilder для OWASP - это определение атрибутов 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 Index содержит сводку типов атрибутов. Он не упоминает некоторые условные вещи, такие как <input type=URL value=...>, но если вы сканируете этот список для действительного URL и друзей, вы должны получить достойное представление о что добавляет HTML5. Также представлен информационный атрибуты HTML 4 с типом %URI.

Белый список ваших протоколов очень похож на Cye JSON whitelists, которые используются Caja JS HTML sanitizer.

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

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

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

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

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

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

Ответ 2

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

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

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

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

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

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

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

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

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

Ответ 3

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

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

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

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

Только мои 2 цента.