Строгая проверка HTML и фильтрация в PHP

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

Основная цель — отфильтровать XSS и подобные гадости, которые могут быть введены через веб-формы. Вторичная цель - ограничить поломку содержимого HTML, введенного нетехническими пользователями, например. через WYSIWYG-редактор с HTML-представлением.

Я рассматриваю возможность использования HTML Purifier или своего собственного с помощью синтаксического анализатора HTML DOM для выполнения такого процесса, как HTML(грязный )->DOM(грязный)->фильтр->DOM(чистый)->HTML(чистый).

Можете ли вы описать успехи этих или других более простых стратегий, которые также эффективны? Есть какие-то подводные камни, на которые стоит обратить внимание?


person Barry Austin    schedule 13.10.2008    source источник


Ответы (4)


Я протестировал все известные мне эксплойты на HTML Purifier, и все прошло очень хорошо. Он фильтрует не только HTML, но также CSS и URL-адреса.

Как только вы сужаете элементы и атрибуты до невинных, подводные камни заключаются в содержимом атрибутов — javascript: псевдо-URL (IE разрешает символы табуляции в имени протокола — java	script: по-прежнему работает) и свойствах CSS, которые запускают JS.

Разбор URL-адресов может быть сложным, например. они действительны: http://spoof.com:[email protected] или //evil.com. Интернационализированные домены (IDN) могут быть записаны двумя способами — Unicode и punycode.

Воспользуйтесь HTML Purifier — в нем реализовано большинство из них. Если вы просто хотите исправить сломанный HTML, используйте HTML Tidy (он доступен как расширение PHP).

person Kornel    schedule 13.10.2008
comment
Оказывается, в 2008 году это было далеко не безопасно, эти эксплойты были обнаружены в 2011 году: secunia.com/advisories/43907, 2010 г.: secunia.com/advisories/39613 Урок: обязательно всегда обновляйте установка фильтра. - person Cheekysoft; 01.09.2011

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

Также помните о допустимом внешнем виде:

<img src="http://www.mysite.com/logout" />

и

<a href="javascript:alert('xss hole');">click</a>
person Ross    schedule 13.10.2008
comment
Спасибо, Росс, это отличные примеры входных данных, которые следует отфильтровывать. Но ответ, который я ищу, также будет включать методы и решения. - person Barry Austin; 14.10.2008
comment
Первый пример (который является отсылкой к статье codinghorror: codinghorror.com/blog/archives /001171.html) на самом деле не имеет значения, поскольку «дыра» зависит от характера этого URL, а не от синтаксиса этого конкретного фрагмента HTML. - person Bobby Jack; 14.10.2008
comment
Есть еще полезные правила, которые можно применить к первому, например, разрешить тег ‹img› только тогда, когда атрибут src соответствует регулярному выражению /^http:\/\/localsite.com\/uploaded_images\/[\w-] *\.(png|jpg|gif)$/i. - person Barry Austin; 14.10.2008

Я успешно использовал HTML Purifier, и у меня не было никаких xss или других нежелательных входных фильтров. Я также запускаю очистку HTML через расширение Tidy, чтобы убедиться, что оно также проверяется.

person Oscar M.    schedule 13.10.2008

У W3C есть большой пакет с открытым исходным кодом для проверки HTML, доступный здесь:

http://validator.w3.org/

Вы можете загрузить пакет для себя и, вероятно, реализовать то, что они делают. К сожалению, похоже, что многие парсеры DOM, похоже, готовы изменить правила, чтобы выделить код HTML «в дикой природе», так что это хорошая идея, чтобы мастера сказали вам, что не так, а не оставлять это на усмотрение. более практичный инструмент — существует множество веб-сайтов, которые не являются идеальными HTML-совместимыми, но которые мы все еще используем каждый день.

person Robert Elwell    schedule 13.10.2008
comment
Проверка против DTD вообще не защищает от XSS. - person Kornel; 14.10.2008
comment
Точно, я не думаю, что это то, что Барри имел в виду под проверкой — подумайте о проверке или проверке данных, а не о проверке стандартов. Это поможет против искаженного HTML;) - person Ross; 14.10.2008