Подтвердить что ты не робот

Является ли 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

4b9b3361

Ответ 1

Как следует из его названия, 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 of 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 без аргумента белого списка:

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

Ответ 2

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

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

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

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

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

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

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

Ответ 3

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

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

Ответ 4

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

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

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

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