Markdown и XSS

Хорошо, поэтому я читал об уценке здесь, в SO и в другом месте, и шаги между пользовательским вводом и db обычно задаются как

  • конвертировать уценку в html
  • sanitize html (w/whitelist)
  • вставить в базу данных

но для меня имеет смысл сделать следующее:

  • санизировать уценку (удалить все теги - нет исключений)
  • конвертировать в html
  • вставить в базу данных

Я что-то упустил? Мне кажется, что это почти xss-proof

Ответ 1

Пожалуйста, просмотрите эту ссылку:

http://michelf.com/weblog/2010/markdown-and-xss/

> hello <a name="n"
> href="javascript:alert('xss')">*you*</a>

становится

<blockquote>
 <p>hello <a name="n"
 href="javascript:alert('xss')"><em>you</em></a></p>
</blockquote>

∴ вы должны дезинфицировать после преобразования в HTML.

Ответ 2

Есть две проблемы с тем, что вы предложили:

  • Я не вижу, чтобы ваши пользователи могли форматировать сообщения. Например, вы использовали Markdown для создания списка нумерованных списков. В предлагаемом мире no-tags-no-exceptions я не вижу, как конечный пользователь сможет это сделать.
  • Значительно важнее: При использовании Markdown как "родного" языка форматирования и белого списка других доступных тегов вы ограничиваете не только входную сторону мира, но и выход. Другими словами, если ваш движок отображения ожидает Markdown и разрешает только белый контент, даже если (не дай бог) кто-то попадает в базу данных и вводит какой-то неприятный вредоносный код в кучу сообщений, фактический сайт и его пользователи защищены потому что вы также дезинфицируете его на дисплее.

В Интернете есть некоторые хорошие ресурсы о санитарии выпуска:

Ответ 3

Ну, конечно, удаление/экранирование всех тегов сделает язык разметки более безопасным. Однако весь смысл Markdown заключается в том, что он позволяет пользователям включать произвольные HTML-теги, а также собственные формы разметки (*). Когда вы разрешаете HTML, вы все равно должны очищать/белить список, так что вы можете также сделать это после преобразования уценки, чтобы поймать все.

*: Это дизайнерское решение, с которым я вообще не согласен, и тот, который, как мне кажется, не оказался полезным в SO, но это дизайнерское решение, а не ошибка.

Кстати, шаг 3 должен быть "выводим на страницу"; это обычно происходит на выходном каскаде с базой данных, содержащей исходный текст.

Ответ 4

  • вставить в базу данных
  • конвертировать уценку в html
  • sanitize html (w/whitelist)

Perl

use Text::Markdown ();
use HTML::StripScripts::Parser ();

my $hss = HTML::StripScripts::Parser->new(
   {
       Context         => 'Document',
       AllowSrc        => 0,
       AllowHref       => 1,
       AllowRelURL     => 1,
       AllowMailto     => 1,
       EscapeFiltered  => 1,
   },
   strict_comment => 1,
   strict_names   => 1,
);

$hss->filter_html(Text::Markdown::markdown(shift))

Ответ 5

  • конвертировать уценку в html
  • sanitize html (w/whitelist)
  • вставить в базу данных

Здесь предположения

  • Учитывая опасный HTML, дезинфицирующее средство может создавать безопасный HTML.
  • Определение безопасного HTML не изменится, поэтому, если это безопасно, когда я вставляю его в БД, он безопасен, когда я его извлекаю.
  • sanitize markdown (удалить все теги - без исключений)
  • конвертировать в html
  • вставить в базу данных

Здесь предположения

  • Учитывая опасную уценку, дезинфицирующее средство может произвести уценку, что при конвертации в HTML другой программой будет безопасно.
  • Определение безопасного HTML не изменится, поэтому, если это безопасно, когда я вставляю его в БД, он безопасен, когда я его извлекаю.

Дезинфицирующее средство для маркировки должно знать не только о опасном HTML и опасной уценке, но и о том, как работает программа уценки- > конвертер HTML. Это делает его более сложным и, скорее всего, ошибочным, чем более простая небезопасная функцияHTML- > safeHTML выше.

В качестве конкретного примера, "удалить все теги" предполагает, что вы можете идентифицировать теги и не будет работать против атак UTF-7. Там могут быть другие атаки кодирования, которые делают это допущение спорным, или может быть ошибка, вызывающая преобразование программы markdown- > HTML (full-width '<', экзотические символы пробела, разделенные меткой, SCRIPT) в тег <script>.

Наиболее безопасным будет:

  • sanitize markdown (удалить все теги - без исключений)
  • конвертировать уценку в HTML
  • санировать HTML
  • вставить в столбец DB, помеченный как опасный
  • повторно очищать HTML каждый раз, когда вы извлекаете этот столбец из базы данных

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