Как предотвратить атаки с использованием Javascript-инъекций в пользовательском HTML-коде

Я сохраняю отправленный пользователем HTML (в базе данных). Я должен предотвратить атаки с использованием JavaScript-инъекций. Самое опасное, что я видел, - это JavaScript в style="expression(...)".

В дополнение к этому изрядное количество действительного пользовательского контента будет включать специальные символы и конструкции XML, поэтому я бы по возможности избегал подхода с использованием белого списка. (Список всех допустимых элементов и атрибутов HTML).

Примеры строк атаки JavaScript:

1.

"Hello, I have a
<script>alert("bad!")</script>
problem with the <dog>
element..."
"Hi, this <b
style="width:expression(alert('bad!'))">dog</b>
is black."

Есть ли способ предотвратить такой JavaScript и оставить все остальное нетронутым?

Единственное решение, которое у меня есть до сих пор, - использовать регулярное выражение для удаления определенных шаблонов. Он решает случай 1, но не случай 2.

Среда - это, по сути, стек Microsoft:

  • SQL Server 2005
  • C # 3.5 (ASP.NET)
  • JavaScript и jQuery.

Я бы хотел, чтобы узким местом был уровень ASP.NET - любой может создать неверный HTTP-запрос.

Редактировать

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

Какой парсер позволит мне просто удалить плохие части? Плохой частью может быть целый элемент, но как насчет тех скриптов, которые находятся в атрибутах? Я не могу удалить < a hrefs > волей-неволей.


person Jeff Meatball Yang    schedule 02.06.2009    source источник


Ответы (7)


Вы думаете, что это все? Проверьте это.

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

ИЗМЕНИТЬ:

К сожалению, я не знаком с .NET, но вы можете проверить собственную битву stackoverflow с XSS (https://blog.stackoverflow.com/2008/06/safe-html-and-xss/) и код, который был написан для анализа HTML, размещенного на этом сайте: ссылка Archive.org - очевидно, вам может потребоваться изменить это потому что ваш белый список больше, но с этого вы должны начать.

person Paolo Bergantino    schedule 02.06.2009
comment
Спасибо, я использую этот сайт в качестве испытательной площадки. Я успешно удалил все, что похоже на ‹script›, поэтому мне нужно получить те, которые не ... то есть выражение :, javascript :, vbscript: и т. Д. Не могли бы вы предложить синтаксический анализатор, который может это сделать? ? - person Jeff Meatball Yang; 03.06.2009
comment
Если ваш подход заключается в удалении опасных вещей, ваш код будет уязвим для инъекций. Единственный безопасный подход - иметь белый список специально разрешенных элементов и атрибутов. - person Miles; 03.06.2009
comment
Спасибо за ответ. Я боялся, что ответом был белый список. :) - person Jeff Meatball Yang; 03.06.2009
comment
Джефф, попробуйте эту строку: <scr<script>ipt>. Ура XSS! Черные списки работать не будут. Независимо от того, длинный у вас белый список или нет, его нельзя занести в черный список. Веб-сайт OWASP может очень помочь, если вы хотите прочитать больше статей об этом. - person Chuck Vose; 18.04.2013
comment
Не могли бы вы объяснить, что такое белый список и как он работает / удаляет плохие вещи? - person rogerdpack; 04.10.2016

Белый список для элементов и атрибутов - это единственный приемлемый выбор, на мой взгляд. Все, что не входит в ваш белый список, должно быть вырезано или закодировано (замените ‹> &" на сущности). Также не забудьте проверить значения в допустимых атрибутах.

Что-нибудь меньшее, и вы открываете себя для проблем - известных эксплойтов или тех, которые будут обнаружены в будущем.

person BarelyFitz    schedule 02.06.2009

Единственный действительно безопасный способ - использовать белый список. Кодируйте все, а затем конвертируйте разрешенные коды обратно.

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

person Guffa    schedule 02.06.2009
comment
Я выяснил на собственном горьком опыте. Теперь мы используем экранирование и белый список. - person Jeff Meatball Yang; 23.06.2009

В настоящее время лучшим вариантом является использование заголовка политики безопасности контента, подобного этому :

Content-Security-Policy: default-src 'self';

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

Однако это не будет работать в старых браузерах.

person Adam    schedule 13.09.2017
comment
Помешает ли это нам использовать CDN? - person Daniel Wu; 23.07.2020
comment
@DanielWu: да, но вы можете внести домен CDN или хэш файла в белый список. - person Adam; 23.07.2020

По сути, как сказал Паоло, вы должны попытаться сосредоточиться на том, что пользователям разрешено делать, а не пытаться отфильтровать то, что они не должны делать.

Сохраните список разрешенных тегов HTML (например, b, i, u ...) и отфильтруйте все остальное. Вероятно, вы также захотите удалить все атрибуты разрешенных тегов HTML (например, из-за вашего второго примера).

Другое решение - ввести так называемый BB-код, который используют многие форумы. Он имеет синтаксис, аналогичный HTML, но начинается с идеи белого списка разрешенного кода, который затем преобразуется в HTML. Например, [b] example [/ b] приведет к example. Убедитесь, что при использовании BB-кода заранее отфильтрованы HTML-теги.

person Aistina    schedule 02.06.2009
comment
Я опасаюсь, что контент будет включать множество математических и программных конструкций (XML, C # и т. Д.), Поэтому я бы предпочел избежать белого списка. - person Jeff Meatball Yang; 03.06.2009

какой код на стороне сервера вы используете? В зависимости от того, какое количество или способы вы можете отфильтровать вредоносный скрипт, это опасная территория. Даже опытных профессионалов ловят: http://www.codinghorror.com/blog/archives/001167.html

person Chris Simpson    schedule 02.06.2009

Вы можете использовать эту функцию ограничения.

function restrict(elem){
  var tf = _(elem);
  var rx = new RegExp;
  if(elem == "email"){
       rx = /[ '"]/gi;
  }else if(elem == "search" || elem == "comment"){
    rx = /[^a-z 0-9.,?]/gi;
  }else{
      rx =  /[^a-z0-9]/gi;
  }
  tf.value = tf.value.replace(rx , "" );
}
person themba    schedule 28.01.2015
comment
сброс кода без каких-либо объяснений вызовет только недоумение, особенно если он даже не работает: что это значит - ›_(elem)? - person vsync; 11.05.2017