Как защитить себя от XSS, когда вы разрешаете людям публиковать коды встраивания RAW? - PullRequest
19 голосов
/ 20 марта 2010

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

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

Это делается с помощью выражений REGEX? И есть ли класс PHP для этого?

Спасибо

Ответы [ 7 ]

25 голосов
/ 22 марта 2010

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


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

Пара интересных вещей:

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

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


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


Цитирование домашней страницы HTMLPurifier:

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

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



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

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


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

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


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

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

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

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

    (замена «videoID» наидентификатор видео, конечно)

    Вы получите некоторый канал ATOM, если видео действительно;и «Неверный идентификатор», если он не

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


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

    ЛучшийРешение для извлечения части данных из строки HTML обычно заключается в следующем:

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

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

2 голосов
/ 20 марта 2010

Взгляните на htmlpurifier, чтобы начать.http://htmlpurifier.org/

1 голос
/ 27 марта 2010

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

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

1. Сначала ==> подружитесь с stripos()

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

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

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

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

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

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

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

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

0 голосов
/ 29 марта 2010

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

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

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

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

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

0 голосов
/ 28 марта 2010

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

0 голосов
/ 28 марта 2010

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

0 голосов
/ 26 марта 2010

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...