提问人:Pekka 提问时间:4/26/2011 最后编辑:CommunityPekka 更新时间:5/9/2023 访问量:25003
strip_tags() 是否容易受到脚本攻击?
Is strip_tags() vulnerable to scripting attacks?
问:
是否存在已知的 XSS 或其他攻击使其通过
$content = "some HTML code";
$content = strip_tags($content);
echo $content;
?
手册有警告:
此函数不会修改您允许使用allowable_tags的标签上的任何属性,包括调皮的用户在发布将向其他用户显示的文本时可能滥用的样式和 onmouseover 属性。
但这仅与使用参数有关。allowable_tags
如果未设置允许的标签,是否容易受到任何攻击?strip_tags()
克里斯·希弗利特(Chris Shiflett)似乎说这是安全的:
使用成熟的解决方案
如果可能,请使用成熟的现有解决方案,而不是尝试创建自己的解决方案。像 strip_tags() 和 htmlentities() 这样的函数是不错的选择。
这是正确的吗?如果可能,请引用来源。
我知道 HTML 净化器、htmlspecialchars() 等 - 我不是在寻找清理 HTML 的最佳方法。我只想知道这个具体问题。这是这里提出的一个理论问题。
答:
剥离标签是完全安全的 - 如果您所做的只是将文本输出到 html 正文。
将其放入 mysql 或 url 属性中不一定安全。
评论
顾名思义,应该删除所有 HTML 标签。我们唯一能证明它的方法是分析源代码。下一个分析适用于呼叫,没有针对白名单标签的第二个参数。strip_tags
strip_tags('...')
首先,关于HTML标签的一些理论:标签以a开头,后跟非空格字符。如果此字符串以 开头,则不应对其进行解析。如果此字符串以 开头,则将其视为注释,并且不应解析以下文本。注释以 结尾,在此类注释中,允许使用 和 等字符。属性可以出现在标记中,它们的值可以选择用引号字符(或 )括起来。如果存在这样的引号,则必须将其关闭,否则如果遇到 a,则不会关闭标记。<
?
!--
-->
<
>
'
"
>
该代码在Firefox中被解释为:<a href="example>xxx</a><a href="second">text</a>
<a href="http://example.com%3Exxx%3C/a%3E%3Ca%20href=" second"="">text</a>
PHP 函数strip_tags
在 ext/standard/string.c 的第 4036 行中引用。该函数调用内部函数 php_strip_tags_ex。
存在两个缓冲区,一个用于输出,另一个用于“内部 HTML 标记”。名为 的计数器保存左尖括号 () 的数目。
该变量包含引号字符(或 ),如果有,否则。最后一个字符存储在变量 中。depth
<
in_q
'
"
0
lc
函数包含五种状态,其中三种在函数上方的描述中提到。基于此信息和函数体,可以派生出以下状态:
- 状态 0 是输出状态(不在任何标记中)
- 状态 1 表示我们位于一个普通的 html 标签中(标签缓冲区包含
<
) - 状态 2 表示我们在 php 标签内
- 状态 3:我们从输出状态中遇到 and 字符(标签缓冲区包含
<
!
<!
) - 状态 4:HTML 注释内部
我们只需要注意不要插入任何标签。也就是说,后跟一个非空格字符。第 4326 行检查具有如下描述的字符的大小写:<
<
- 如果在引号内(例如),则忽略该字符(从输出中删除)。
<a href="inside quotes">
<
- 如果下一个字符是空格字符,
则<
添加到输出缓冲区中。 - 如果在 HTML 标记之外,则状态变为 (“inside HTML tag”),最后一个字符设置为
1
lc
<
- 否则,如果在 HTML 标记内,则命名的计数器将递增并忽略该字符。
depth
如果在标签打开时满足 (),则变为(“不在引号中”)和变为(“不在标签中”)。标记缓冲区将被丢弃。>
state == 1
in_q
0
state
0
属性检查(对于字符,如 和 )是在丢弃的标记缓冲区上完成的。所以结论是:'
"
strip_tags没有标签白名单可以安全地包含在标签之外,则不允许使用任何标签。
通过“外部标签”,我的意思是不在标签中,如 .文本可能包含 和 ,如 .结果是无效的 HTML,仍然需要转义,尤其是 .这可以通过 htmlspecialchars()
来完成。<a href="in tag">outside tag</a>
<
>
>< a>>
<
>
&
&
没有白名单参数的描述是:strip_tags
确保返回的字符串中不存在 HTML 标记。
评论
strip_tags()
strip_tags
我无法预测未来的漏洞利用,特别是因为我没有查看过这方面的PHP源代码。但是,由于浏览器接受看似无效的标签(例如)。因此,将来有人可能会利用奇怪的浏览器行为。<s\0cript>
撇开这一点不谈,将输出作为完整的 HTML 块直接发送到浏览器应该永远不会不安全:
echo '<div>'.strip_tags($foo).'</div>'
但是,这并不安全:
echo '<input value="'.strip_tags($foo).'" />';
因为可以很容易地通过并插入脚本处理程序来结束引用。"
我认为总是将杂散转换为(引号也是如此)要安全得多。<
<
根据这个在线工具,这个字符串将被“完美”转义,但是 结果是另一个恶意的!
<<a>script>alert('ciao');<</a>/script>
在字符串中,“真实”标签是 和 ,因为 和 单独不是标签。<a>
</a>
<
script>
我希望我错了,或者只是因为旧版本的 PHP,但最好检查一下您的环境。
评论
var_dump(strip_tags("<<a>script>alert('ciao');<</a>/script>"));
=> "alert('ciao');"
在 PHP 7.1.2 中。它似乎在遇到 an 之后删除了所有内容。<
>
alert('ciao');
是的,strip_tags(
) 容易受到脚本攻击,直到(至少)PHP 8。不要用它来阻止 XSS。相反,您应该使用 filter_input()。
易受攻击的原因是它不递归运行。也就是说,它不会检查在去除有效标签后是否还会保留有效标签。例如,字符串
将成功剥离标签,但看不到此离开
。strip_tags()
<<a>script>alert(XSS);<</a>/script>
<a>
<script>alert(XSS);</script>
这可以在这里(在安全的环境中)看到。
评论
strip_tags
alert('XSS');
我刚刚能够在 href 中注入脚本 pn PHP 8:strip_tags()
测试使用:
<a href="javascript:alert(1)">Click me!</a>
显然,这需要用户交互,但通过此功能。
类似于 strip_tags() 是否容易受到脚本攻击?但没有额外的插入符号。
评论
上一个:使用二进制排序规则有什么影响?
评论
strip_tags
strip_tags()