Безопасное отображение иностранного HTML

У меня есть приложение, которое должно безопасно отображать чужие HTML-данные (например, текстовые сообщения в кодировке HTML, но не только), т. Е. Удалять попытки XSS и другие неприятные вещи. Но все же сможете отображать HTML так, как он должен выглядеть. Решения, рассмотренные до сих пор, не идеальны:

  1. Чистый HTML с чем-то вроде HTMLPurifier. Работает нормально, но как только размер электронной почты превышает 100 КБ, он становится очень медленным - десятки секунд на одно письмо. Я подозреваю, что любой достаточно безопасный парсер будет настолько медленным в PHP - некоторые электронные письма действительно плохие HTML, я видел такие, которые генерируют 150K HTML для одной страницы текста.
  2. Отображение HTML в iframe - здесь проблема заключается в том, что iframe должен находиться в другом источнике, чтобы быть защищенным от XSS AFAIK, и для этого потребуется другой домен для того же приложения. Настройка приложения с двумя доменами намного сложнее и может быть очень сложной в некоторых настройках (например, хостинг, который дает только одно доменное имя).

Любые другие решения, которые могут достичь этого результата?

2 ответа

Решение

Из моего понимания я не верю.

Проблема в том, что вы можете безопасно удалять HTML-теги только в том случае, если понимаете его структуру, а "понимание его структуры" - это именно то, что представляет собой анализ. Даже если вы найдете другой способ анализа структуры HTML и не называете его синтаксическим анализом, это то, что вы делаете, и это обязательно будет медленной (или небезопасной) формой.

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

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

Работает ли такое жонглирование для ваших сценариев использования, вам, вероятно, придется самим сравнивать.

Слово предостережения: если вы решите заняться этим, знайте, я бы не пошел с подходом iframe. Если вы не фильтруете HTML, вы также разрешаете формы, и это становится (IMO) тривиальным в сочетании со сценариями и CSS, чтобы настроить чрезвычайно убедительный фишинг, например, используя такие трюки, как "это электронное письмо защищено паролем, чтобы продолжить, Пожалуйста, введите ваш пароль".

Одно из возможных решений ( и того, которое использует SO!) - разрешить только определенные типы тегов. <p> а также <br /> в порядке, но <script> прямо

Другие вопросы по тегам