Как я могу позволить моему пользователю вставлять HTML-код без риска? (не только технические риски)

Я разработал веб-приложение, которое позволяет моим пользователям управлять некоторыми аспектами веб-сайта динамически (да, какие-то cms) в среде LAMP (debian, apache, php, mysql)

Ну, например, они создают новости в своей частной области на моем сервере, а затем публикуются на их сайте через запрос cURL (или ajax).

Новость создается с помощью редактора WYSIWYG (fck в данный момент, возможно, tinyMCE в следующем будущем).

Итак, я не могу запретить теги html, но как я могу быть в безопасности? Какие теги я ДОЛЖЕН удалить (javascripts?)? Это в смысле быть безопасным сервером.. но как быть "юридически" безопасным? Если пользователь использует мое приложение для создания xss, могу ли я иметь некоторые юридические проблемы?

Ответ 1

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

Ответ 2

Неважно, что вы хотите удалить, кто-то всегда найдет способ обойти его. В качестве ссылки рассмотрим этот XSS Cheat Sheet.

В качестве примера, как вы собираетесь удалить эту действительную атаку XSS:

<IMG SRC=&#x6A&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3A&#x61&#x6C&#x65&#x72&#x74&#x28&#x27&#x58&#x53&#x53&#x27&#x29>

Ваш лучший вариант - разрешить только подмножество допустимых тегов и удалить что-нибудь еще. Эта практика известна как White Listing и является лучшим методом предотвращения XSS (помимо запрета HTML).

Также используйте обертку в своем тестировании; как можно больше на вашем сайте, и попытайтесь найти некоторые способы выполнения XSS.

Ответ 3

Общей лучшей стратегией здесь является белый список конкретных тегов и атрибутов, которые вы считаете безопасными, и избежать/удалить все остальное. Например, разумный белый список может быть <p>, <ul>, <ol>, <li>, <strong>, <em>, <pre>, <code>, <blockquote>, <cite>. В качестве альтернативы рассмотрите удобную для человека разметку, например Textile или Markdown, который можно легко преобразовать в безопасный HTML.

Ответ 4

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

<scr<script>ipt etc="...">

Удаление из этого оставит

<script etc="...">

Ответ 6

Помощник по безопасности Kohana довольно хорош. Из того, что я помню, он был взят из другого проекта.

Однако я протестировал

<IMG SRC=&#x6A&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3A&#x61&#x6C&#x65&#x72&#x74&#x28&#x27&#x58&#x53&#x53&#x27&#x29>

Из ответ LFSR Consulting, и он избежал его правильно.

Ответ 7

Если слишком сложно удалить теги, вы можете отклонить все html-данные до тех пор, пока пользователь не введет действующий. Я бы отклонил html, если он содержит следующие теги:

фреймами, рамка, IFrame, script, объект, код вставки, апплет.

Также теги, которые вы хотите запретить, - это: head (и подтеги), body, html, потому что вы хотите предоставить их сами, и вы не хотите, чтобы пользователь манипулировал вашими метаданными.

Но, вообще говоря, позволяя пользователю предоставлять свой собственный HTML-код, всегда возникают некоторые проблемы с безопасностью.

Ответ 8

Возможно, вы захотите рассмотреть, а не разрешить HTML вообще, внедрить некоторые средства для HTML, такие как BBCode или Markdown.

Ответ 9

Я использую эту функцию php strip_tags, потому что я хочу, чтобы пользователь мог отправить сообщение безопасно, и я разрешаю всего несколько тегов, которые можно использовать в сообщении таким образом, никто не может взломать ваш сайт с помощью script инъекции, поэтому я думаю, что strip_tags - лучший вариант

Нажмите здесь для кода для этой php-функции

Ответ 10

code that I should have just copy/pasted instead of screenshotting

Это очень хорошая функция в php, которую вы можете использовать.

$string = strip_tags($_POST['comment'], "<b>");