Является ли strip_tags () уязвимым для сценариев атак?

Существует ли известная XSS или другая атака, которая

$content = "some HTML code"; $content = strip_tags($content); echo $content; 

?

В руководстве есть предупреждение:

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

но это связано только с использованием параметра allowable_tags.

Без установленного набора меток strip_tags() уязвим для любой атаки?

Крис Шифлетт, кажется, говорит, что это безопасно:

Использовать зрелые решения

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

это верно? Если возможно, укажите источники.

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

Ссылка: strip_tags() реализация в исходном коде PHP

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

Во-первых, некоторая теория о тегах HTML: тег начинается с < сопровождаемого символами без пробелов. Если эта строка начинается с ? , он не должен анализироваться . Если эта строка начинается с символа !-- , это считается комментарием, и следующий текст не должен анализироваться. Комментарий заканчивается с помощью --> , внутри такого комментария допускаются символы типа < и > . Атрибуты могут встречаться в тегах, их значения могут быть дополнительно окружены символом кавычки ( ' или " ). Если такая цитата существует, она должна быть закрыта, иначе, если a > встречается, тэг не закрывается.

Код <a href="example>xxx</a><a href="second">text</a> интерпретируется в Firefox как:

 <a href="http://example.com%3Exxx%3C/a%3E%3Ca%20href=" second"="">text</a> 

Функция PHP strip_tags в строке 4036 файла ext / standard / string.c . Эта функция вызывает внутреннюю функцию php_strip_tags_ex .

Существуют два буфера, один для вывода, другой для «внутри HTML-тегов». Счетчик с depth держит число угловых скобок ( < ).
Переменная in_q содержит символ кавычки ( ' или " ), если он есть, и 0 противном случае последний символ сохраняется в переменной lc .

Функции содержат пять состояний, три упомянутые в описании выше функции. На основе этой информации и тела функции могут быть получены следующие состояния:

  • Состояние 0 – это состояние вывода (не в любом теге)
  • Состояние 1 означает, что мы находимся внутри нормального тега html (буфер тега содержит < )
  • Состояние 2 означает, что мы находимся внутри тега php
  • Состояние 3: мы пришли из состояния вывода и столкнулись с < и ! символов (буфер тега содержит <! )
  • Состояние 4: внутри комментария HTML

Нам нужно просто быть осторожным, чтобы ни один тег не мог быть вставлен. То есть, < сопровождается символом без пробелов. Строка 4326 проверяет регистр с символом < который описан ниже:

  • Если внутри кавычек (например, <a href="inside quotes"> ), символ < игнорируется (удаляется из вывода).
  • Если следующий символ является символом пробела, < добавляется в выходной буфер .
  • если вне тега HTML, состояние становится 1 («внутри HTML-тега»), а последний символ lc установлен в <
  • В противном случае, если внутри тега HTML, счетчик с именем depth увеличивается и символ игнорируется.

Если > встречается, когда тег открыт ( state == 1 ), in_q становится 0 («не в цитате»), а state становится 0 («не в теге»). Буфер тега отбрасывается.

Проверки атрибутов (для символов типа ' и " ) выполняются в буфере тегов, который отбрасывается. Таким образом, вывод следующий:

strip_tags без ярлыка тега безопасно для включения внешних тегов, никакой тег не будет разрешен.

Под «внешними тегами» я имею в виду не теги, как в <a href="in tag">outside tag</a> . Текст может содержать < и > хотя, как в >< a>> . Результат недействителен HTML, хотя, < , > и еще нужно избежать, особенно & . Это можно сделать с помощью htmlspecialchars() .

Описание для strip_tags без аргумента whitelist будет:

Уверен, что в возвращаемой строке не существует HTML-тега.

Я не могу предсказать будущие эксплойты, тем более, что я не смотрел исходный код PHP для этого. Тем не менее, в прошлом были эксплойты из-за того, что браузеры принимали, казалось бы, недопустимые теги (например, <s\0cript> ). Поэтому вполне возможно, что в будущем кто-то сможет использовать нечетное поведение браузера.

В стороне, отправляя вывод непосредственно в браузер, поскольку полный блок HTML никогда не должен быть неуверенным:

 echo '<div>'.strip_tags($foo).'</div>' 

Однако это небезопасно:

 echo '<input value="'.strip_tags($foo).'" />'; 

потому что можно легко закончить цитату через " и вставить обработчик сценария.

Я думаю, что гораздо безопаснее всегда конвертировать бездействующие < в &lt; (и то же самое с кавычками).

Стрип-теги совершенно безопасны – если все, что вы делаете, выводит текст в тело html.

Не обязательно безопасно помещать его в атрибуты mysql или url.

Согласно этому онлайн-инструменту , эта строка будет «отлично» экранирована, но результат будет другим злонамеренным!

 <<a>script>alert('ciao');<</a>/script> 

В строке «реальные» теги <a> и </a> , так как только < и script> не являются тегами.

Надеюсь, я ошибаюсь или что это просто из-за старой версии PHP, но лучше проверить свою среду.