Как защитить себя от XSS, когда вы разрешаете людям публиковать НЕОБРАБОТАННЫЕ коды встраивания?


Tumblr и другие сайты блогов позволяют людям публиковать встроенные коды видео с YouTube и всех видеосетей.

Но как они фильтруют только объектный код flash и удаляют любые другие html или скрипты? и даже у них есть автоматический код, который сообщает вам, что это неверный видеокод.

Делается ли это с помощью РЕГУЛЯРНЫХ выражений? И есть ли класс PHP для этого?

Спасибо

 18
Author: Ryan, 2010-03-20

7 answers

Вообще говоря, использование регулярных выражений не является хорошим способом работы с HTML: HTML недостаточно регулярен для регулярных выражений: в стандартах допускается слишком много вариаций... И браузеры даже принимают недопустимый HTML-код!


В PHP, поскольку ваш вопрос помечен как php, отличным решением, которое существует для фильтрации пользовательского ввода, является Очиститель HTMLPurifier инструмент.

Есть пара интересных вещей:

  • Это позволяет вы указываете , какие конкретные теги разрешены
  • Для каждого тега вы можете определить , какие конкретные атрибуты разрешены

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


И если вы укажете только список тегов и атрибутов, которые не могут причинить вреда, будут сохранены только они - и риски инъекции значительно снижены.


Цитируя домашнюю страницу HTMLPurifier:

Очиститель HTML соответствует стандартам Библиотека фильтров HTML, написанная на PHP.
Очиститель HTML не только удалит весь вредоносный код (более известный как XSS) с тщательно проверенным, безопасным, но разрешительным белым списком, он также обеспечит соответствие ваших документов стандартам, что возможно только при всестороннем знании W3C технические характеристики.

Да, еще одна замечательная вещь заключается в том, что код, который вы получаете в качестве вывода, является действительным.



Конечно, это позволит вам только очистить/отфильтровать/очистить ввод HTML; это не позволит вам проверить, что URL, используемый пользователем, является и тем, и другим:

  • правильно; т.е. указывает на реальное содержание
  • "ОК", как определено на вашем веб-сайте; т.е., например, никакой наготы,...


По поводу второго пункта, с этим мало что можно поделать: лучшим решением будет либо:

  • Попросите модератора принять/отклонить содержимое, прежде чем оно будет размещено в Интернете
  • Дайте пользователям веб-сайта возможность помечать некоторый контент как неуместный, чтобы модератор принял меры.

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


Однако по поводу первого пункта, есть надежда: некоторые службы, размещающие контент, имеют API, которые вы, возможно, захотите/сможете использовать.

Например, Youtube предоставляет API - см. Руководство разработчика: PHP.

В вашем случае раздел Получение определенной записи видео выглядит многообещающе: если вы отправите HTTP-запрос на URL-адрес, который выглядит следующим образом:

http://gdata.youtube.com/feeds/api/videos/videoID

( Замена "видеоиДА" идентификатором видео, конечно)

Ты получишь немного АТОМА канал, если видео является действительным; и "Недопустимый идентификатор", если это не

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


Теперь, чтобы извлечь идентификатор видео из вашей HTML-строки... Если вы думаете об использовании регулярного выражения, вы ошибаетесь;-)

Лучшим решением для извлечения части данных из строки HTML, как правило, является :

  • Загрузите HTML с помощью синтаксического анализатора DOM ; DOMDocument::loadHTML как правило, это довольно полезно, здесь
  • Просмотрите документ , используя методы DOM; либо, в зависимости от вашей ситуации :
    • DOMDocument::getElementsByTagName, если вам нужно выполнить итерацию по всем элементам с определенным именем тега; было бы здорово выполнить итерацию по всем тегам <object> или <embed>, например
    • Или, если вам нужно что-то более сложное, вы можете выполнить запрос XPath, используя класс DOMXPath и его DOMXPath::query метод.

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

 24
Author: Pascal MARTIN, 2010-03-29 17:15:22

Для начала взгляните на htmlpurifier. http://htmlpurifier.org/

 2
Author: goat, 2010-03-20 04:40:55

Я реализовал алгоритм для этого для компании, в которой я работаю. Это работает просто отлично. НО это было довольно сложно реализовать.

Я бы определенно проверил HTMLPurifier, чтобы посмотреть, легко ли это работает для вас. Если вы настаиваете на том, чтобы делать это по-старому, как я, вот основные шаги:

1. Прежде всего ==> подружитесь с stripos()

2. Вы должны создать рекурсивную функцию для определения тегов запуска и остановки виджета, которая включает все комбинации <embed></embed> или <embed/> (самозакрывающиеся) или <object></object>... или <object><params>...<embed/></object>

3. После этого вы должны проанализировать все атрибуты и параметры.

4. Теперь все теги <object> должны иметь теги <param> в качестве дочерних элементов. Вы должны проанализировать все это, чтобы получить все данные, необходимые для окончательного создания нового тега встраивания или объекта. Особенно важны параметры и атрибуты, которые соответствуют, высота, источник данных.

5. Теперь вы не знаете, заключены ли атрибуты в один или двойные кавычки, поэтому ваш код должен быть снисходительным в этом отношении. Кроме того, вы не знаете, является ли код действительным или правильно сформированным. Таким образом, он должен уметь обрабатывать вложенные теги встраивания/объектов, теги встраивания, которые неправильно вложены и т. Д. И т. Д... Поскольку это пользовательский контент, вы не можете по-настоящему знать и доверять вводимым данным. Вы увидите, что существует множество комбинаций.

6. Если вам удастся проанализировать внедренный элемент со всеми его атрибутами (или элемент объекта и его дочерние параметры), белый список из доменов легко...

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

Это хорошая тренировка, но если бы я был там, где ты... Не начинай идти по этой дороге.

Рекомендация: Попробуйте найти что-нибудь готовое, с открытым исходным кодом!

 1
Author: Vidar Vestnes, 2010-03-26 22:23:33

Это никогда не будет безопасно. В браузерах есть те забавные маленькие функции, которые помогают людям отображать содержимое своих страниц, даже если html является беспорядочным. Есть бесконечные возможности что-то сделать:)

Проверьте здесь , чтобы увидеть верхушку айсберга

Что вам нужно сделать, так это использовать один вход только для ссылки и дополнительные входы для ширины и высоты и отфильтровать их. ЗАТЕМ создайте тег объекта Самостоятельно.

Это может быть безопасным.

 0
Author: naugtur, 2010-03-26 10:32:02

Http://php.net/manual/en/function.strip-tags.php и разрешить определенные теги?

 0
Author: Yawn, 2010-03-27 23:00:45

Самое простое и элегантное решение: Разрешение HTML и предотвращение XSS@ shiflett.org .
Использование всевозможных "очистителей HTML" более чем бессмысленно. Извините, но я не понимаю людей, которым нравится использовать эти раздутые библиотеки, когда есть гораздо более простое решение.

 0
Author: Dor, 2010-03-28 19:39:24

Если вы хотите сделать свой сайт "безопасным" от уязвимостей, подход с использованием белого списка - это (единственный) способ . Я бы рекомендовал безопасно избегать всего пользовательского контента, и только разметка белого списка, которую вы знаете, безопасна и работает на вашем сайте. Это означает не только теги , но и встраивания flash.

Например, если вы хотите разрешить встраивание любого youtube, напишите регулярное выражение проверки, которое ищет код встраивания, который они генерируют. Отказывайтесь принимать любые другие (или просто отобразите его как экранированную разметку). Это можно проверить. Забудьте всю эту ерунду с анализом.

Если вы также хотите добавить видео vimeo, то посмотрите код встраивания, который они предоставляют, и примите это также.

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

После того, как простая версия алгоритма заработает, вы можете вернуться и сделать ее лучше. Вы может "временно" принимать контент с URL-адресами, сценариями и т. Д., Которые не проходят через ваш белый список, И иметь процесс администратора для добавления утвержденных регулярных выражений в вашу процедуру экранирования вывода. Таким образом, законные пользователи не остаются в стороне, но вы не открываете себя для атак такого рода.

 0
Author: ndp, 2010-03-29 06:28:06