是否存在已知的XSS或其他攻击使其无法通过

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

echo $content;




manual有一个警告:


  此函数不会修改您使用allowable_tags允许的标签上的任何属性,包括调皮风格的用户在发布将显示给其他用户的文本时可能会滥用的style和onmouseover属性。


但这仅与使用allowable_tags参数有关。

没有设置允许的标签,strip_tags()是否容易受到攻击?

Chris Shiflett似乎很安全:


  使用成熟的解决方案
  
  尽可能使用成熟的现有解决方案,而不要尝试创建自己的解决方案。诸如strip_tags()和htmlentities()之类的函数是不错的选择。


它是否正确?如果可能,请引用来源。

我了解HTML净化器,htmlspecialchars()等。-我不是在寻找消毒HTML的最佳方法。我只想了解这个特定问题。 here这是一个理论问题。

参考:strip_tags() implementation in the PHP source code

最佳答案

顾名思义,strip_tags应该删除所有HTML标记。我们可以证明这一点的唯一方法是分析源代码。下一个分析适用于strip_tags('...')调用,白名单标签没有第二个参数。

首先,关于HTML标签的一些理论:标签以<开头,后跟非空白字符。如果此字符串以?开头,则为should not be parsed。如果该字符串以!--开头,则将其视为注释,并且不应解析以下文本。注释以-->终止,在这样的注释中,允许使用<>之类的字符。属性可以出现在标签中,其值可以选择用引号字符('")包围。如果存在这样的引号,则必须将其关闭,否则,如果遇到>,则不会关闭标签。

代码<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_tagsline 4036 of ext/standard/string.c中引用。该函数调用internal function php_strip_tags_ex

存在两个缓冲区,一个缓冲区用于输出,另一个缓冲区用于“内部HTML标记”。名为depth的计数器保存尖括号(<)的数量。
变量in_q包含引号字符('")(如果有),否则包含0。最后一个字符存储在变量lc中。

该功能具有五个状态,在功能上方的说明中提到了三个。根据此信息和功能主体,可以得出以下状态:


状态0是输出状态(不在任何标签中)
状态1表示我们在普通html标签内(标签缓冲区包含<
状态2表示我们在php标记内
状态3:我们来自输出状态,遇到了<!字符(标记缓冲区包含<!
状态4:内部HTML注释


我们只需要注意不要插入任何标签。即,<后跟非空格字符。 Line 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标记。

关于php - strip_tags()是否容易受到脚本攻击?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40090947/

10-12 12:51
查看更多