Использование HTML-очистителя на сайте с использованием только текстового ввода

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

У нас есть типичное веб-приложение PHP / LAMP.

Единственный вход, который мы хотим от пользователей, – это простой текст. Мы не приглашаем или не хотим, чтобы пользователи вводили HTML в любой момент. Элементы формы – это в основном базовые текстовые теги ввода. Может быть несколько текстовых полей, флажков и т. Д.

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

Мое решение состоит в том, чтобы использовать htmlspecialchars на всех выводах во время эха на странице.

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

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

Кто прав, а кто не прав?

Есть также целый «выход на вход или выход», но я думаю, что это дискуссия в другое время и место.

благодаря

Как правило, экранирование должно выполняться для контекста и для использования.

Если то, что вы хотите сделать, это вывести простой текст в контексте HTML (и вы это делаете), тогда вам нужно использовать функцию экранирования, которая гарантирует, что вы всегда будете выводить простой текст в контексте HTML. Учитывая базовый PHP, это действительно будет htmlspecialchars($yourString, ENT_QUOTES, 'yourEncoding'); ,

Если вы хотите сделать вывод HTML в контексте HTML (вы этого не сделаете), тогда вы захотите santitise HTML, когда вы выведете его, чтобы предотвратить его от урона – здесь вы будете $purifier->purify($yourString); на выходе.

Если вы хотите сохранить пользовательский ввод текстового текста в базе данных (опять же, если вы это делаете), выполнив инструкции SQL, тогда вы должны либо использовать подготовленные инструкции для предотвращения SQL-инъекции, либо функцию экранирования, специфичную для вашей БД, такую ​​как mysql_real_escape_string($yourString) .

Вы не должны:

  • escape для HTML, когда вы помещаете данные в базу данных
  • дезинфицировать как HTML, когда вы помещаете данные в базу данных
  • дезинфицировать как HTML, когда вы выводите данные как обычный текст

Из них все вредны, хотя и в разной степени. Обратите внимание, что следующее предполагает, что база данных является вашим единственным или каноническим носителем данных для данных (она также предполагает, что SQL-инъекция позаботилась каким-то другим способом – если вы этого не сделаете, это будет вашей основной проблемой):

  • если вы выходите из HTML, когда вы помещаете данные в базу данных, вы полагаетесь на гарантию того, что вы всегда будете выводить данные в контекст HTML; внезапно, если вы хотите просто поместить его в файл открытого текста для печати как есть, вам необходимо декодировать данные перед их выходом.
  • если вы дезинформируете как HTML, когда вы помещаете данные в базу данных, вы уничтожаете информацию, которую пользователь вводит там. Это система обмена сообщениями, и ваш пользователь хотел сказать кому-то еще теги <script> ? Ваш пользователь не может этого сделать – вы уничтожите эту часть своего сообщения!

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

Вы дезинформировали контекст <div> , но поместили свои данные в встроенный элемент? Ваш пользователь может поместить <div> в свой встроенный элемент, заставляя макет разбиться на макет страницы (насколько это раздражает это зависит от вашего макета) или повлиять на восприятие пользователями метаданных (например, упростить фишинг), например это:

  • Имя: Джон Доу
    (Администратор сайта)

Вы санировали в контексте <span> ? Пользователь может использовать другие теги, чтобы влиять на восприятие пользователями метаданных, например:

  • Имя: John Doe (этот пользователь является администратором)

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

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

ТЛ; др

Санизировать как HTML, когда вы выводите как обычный текст, не очень хорошая идея.

Escape / sanitize для использования и случая.

В вашей ситуации вы хотите избежать простого текста для контекста HTML (= использовать htmlspecialchars() ).