Очистите HTML5 с помощью PHP (предотвратите XSS)

Я создаю редактор WYSIWYG с HTML5 и Javascript. Я разрешаю пользователям публиковать чистый HTML через WYSIWYG, поэтому его нужно дезинфицировать.

Основная задача, такая как защита сайта от межсайтового скриптинга (XSS), становится сложной задачей, потому что для PHP не существует современного программного обеспечения для очистки и фильтрации.

HTML Purifier в настоящее время не поддерживает HTML5, и общее состояние выглядит очень плохо (поддержка HTML5 появится не скоро).

Итак, как мне дезинфицировать ненадежный HTML5 с помощью PHP (бэкэнд)?

Варианты пока...

  • Очиститель HTML (отсутствие новых тегов HTML5, атрибутов данных и т. д.)
  • Реализация собственного очистителя с помощью strip_tags() и Tidy или классов/функций DOM PHP
  • Использование некоторых «случайных» реализаций Tidy, таких как http://eksith.wordpress.com/2013/11/23/whitelist-html-sanitizing-with-php/
  • Google Caja (Javascript/облако)
  • htmLawed (есть бета-версия для поддержки HTML5)

Есть ли другие варианты? PHP умирает? ;)


person kaulusp    schedule 04.05.2014    source источник
comment
Вы предотвращаете межсайтовые сценарии с помощью токенов csrf. Любой приличный фреймворк обеспечит простую реализацию. Если вы решите быть ковбоем и свернуть свой собственный, это работает, но, пожалуйста, не жалуйтесь на смерть php.   -  person pguardiario    schedule 04.05.2014
comment
У меня уже есть защита от CSRF, но ее недостаточно. Пользователи по-прежнему могут публиковать (вводить) события JS, стили CSS и т. д. без надлежащей очистки. Должен быть белый список разрешенных тегов и атрибутов HTML5. То, что PHP умирает, было (плохой?) шуткой.   -  person kaulusp    schedule 04.05.2014
comment
Опубликовать стили css? Ты не понимаешь смысла, сынок.   -  person pguardiario    schedule 04.05.2014
comment
‹p class=mainmenu›‹p› ИЛИ ‹div style=height: 100000px;›‹/div›   -  person kaulusp    schedule 04.05.2014
comment
@pguardiario — CSRF и XSS — совершенно разные виды атак (и хотя защита CSRF обычно побеждает отраженные атаки XSS, она мало помогает против сохраненных атак XSS)   -  person Quentin    schedule 04.05.2014
comment
@stacknoob — Что плохого в простом добавлении элементов и атрибутов из HTML 5, которые вы хотите разрешить в белый список?   -  person Quentin    schedule 04.05.2014
comment
@Quentin Как насчет ‹canvas›, атрибутов данных и замены ‹br /› на ‹br› и т. д. - Базовая ‹article› и т. д. может быть выполнимой задачей.   -  person kaulusp    schedule 04.05.2014
comment
@stacknoob — Canvas — это просто элемент, поэтому вы можете добавить его (почему вы хотите разрешить его в качестве пользовательского ввода, я понятия не имею), я сомневаюсь, что легко разрешить произвольные атрибуты data-, но поскольку они явно предназначены для локального расширения сайта в HTML в любом случае, это не имеет значения, вы просто добавляете определенные атрибуты данных, которые вам нужны. В HTML 5 <br /> и <br> эквивалентны, поэтому переход между ними не имеет значения. Разрешение <article> должно быть тривиальным, но я не могу представить момент, когда вы будете запрашивать пользовательский ввод, состоящий из нескольких статей одновременно.   -  person Quentin    schedule 04.05.2014
comment
@ Квентин Ты прав. В частности, в моем случае мне понадобится всего несколько атрибутов данных, и все необходимые теги будут найдены в HTML 4.01/XHTML. Но это не отменяет того факта, что на данный момент у нас нет подходящего очистителя HTML5 для PHP. Или я что-то упускаю?   -  person kaulusp    schedule 04.05.2014


Ответы (2)


PHP предлагает методы синтаксического анализа для защиты от кода PHP/SQL-инъекций (например, mysql_real_escape_string()). Это не относится к HTML/CSS/JavaScript. Почему так?

Во-первых: единственной целью HTML/CSS/Javascript является отображение информации. В значительной степени вам решать, принимать определенные элементы HTML или отклонять их в зависимости от ваших требований.

Во-вторых: из-за очень большого количества элементов HTML/CSS/JS (которое также постоянно увеличивается) невозможно пытаться контролировать HTML. вы не можете ожидать функционального решения.

Вот почему я бы предложил решение сверху вниз. Я предлагаю начать ограничивать все, а затем разрешать только определенное количество тегов. Хорошей основой, вероятно, является использование BBCdode, довольно популярный. Если вы хотите «разблокировать» дополнительные определенные теги помимо BBCode, вы всегда можете добавить их.

По этой причине скрипты, подобные BBCode, популярны на форумах и веб-сайтах (включая переполнение стека). Редакторы WISIGIG предназначены для административного/внутреннего использования, потому что вы не ожидаете, что администратор вашего веб-сайта будет добавлять плохой контент.

подходы снизу-вверх обречены на провал. Дезинфицирующие средства HTML подвержены экспоненциальной сложности и ничего не гарантируют.


ИЗМЕНИТЬ 1


Вы говорите, что это проблема санитарии, а не проблемы с интерфейсом. Я не согласен, потому что, поскольку вы не можете обрабатывать все существующие и будущие объекты HTML, вам лучше ограничить его на уровне внешнего интерфейса, чтобы быть уверенным на 100%.

При этом, возможно, ниже приведено рабочее решение для вас:

  1. вы можете немного очистить свой код, разделив все объекты, кроме тех, которые находятся в белом списке, используя PHP strip_tags().
  2. Вы также можете удалить все оставшиеся атрибуты тегов (свойства), используя PHP preg_replace() с некоторым регулярным выражением.

$string = "put some very dirty HTML here.";
$string = strip_tags($string, '<p><a><span><h1><li><ul><br>');
$string = preg_replace("/<([b-z][b-z0-9]*)[^>]*?(\/?)>/i",'<$1$2>', $string);
echo $string;

Это вернет ваш обработанный текст.

Примечание: я исключил удаление атрибутов для тегов, поскольку вы можете по-прежнему захотеть сохранить свойства href="". отсюда и регулярное выражение [b-z][B-Z].

person Yann    schedule 25.09.2014
comment
Кроме того, на рынке есть несколько хороших редакторов, все под ключ: CKEditor или редактор TinyMCE и т. д. Почему бы не использовать их? - person Yann; 25.09.2014
comment
WYSIWYG лучше подходит для этой пользовательской базы. Я знаю, что они не хотят изучать язык кодирования/синтаксис, например, BBCode. Смысл HTMLPurifier (и подобных) заключается в том, что он ограничивает все, а затем разрешает только определенное количество тегов. Мне нужно всего несколько тегов, например полужирный и курсив, поэтому CKEditor и TinyMCE будут излишними для этого. - person kaulusp; 25.09.2014
comment
Проблема заключается в санации, а не в реализации внешнего интерфейса или экранировании запросов к базе данных. - person kaulusp; 25.09.2014

Я считаю, что идеальным является использование комбинации:

  mysql_real_escape_string(addslashes($_REQUEST['data']));

При записи

и

   stripslashes($data) 

при чтении всегда помогало мне, я думаю, что это лучше, чем

  htmentities($data) on write

и

  html_entity_decode($data) on read
person Peter Manoukian    schedule 25.09.2014