php - strip_tags() 容易受到脚本攻击吗?

标签 php html security xss strip-tags

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

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

echo $content;

manual有警告:

This function does not modify any attributes on the tags that you allow using allowable_tags, including the style and onmouseover attributes that a mischievous user may abuse when posting text that will be shown to other users.

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

没有设置允许的标签strip_tags()容易受到任何攻击吗?

Chris Shiflett似乎说它是安全的:

Use Mature Solutions

When possible, use mature, existing solutions instead of trying to create your own. Functions like strip_tags() and htmlentities() are good choices.

这是正确的吗?如果可能,请引用来源。

我了解 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_tags 引用于 line 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 without a tag whitelist is safe for inclusion outside tags, no tag will be allowed.

我所说的“外部标签”是指不在 <a href="in tag">outside tag</a> 中的标签中。文本可能包含 <>不过,如 >< a>> 所示。但结果不是有效的 HTML,< , >&仍然需要转义,尤其是 & 。这可以通过 htmlspecialchars() 来完成.

strip_tags的描述没有白名单参数将是:

Makes sure that no HTML tag exist in the returned string.

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

相关文章:

php - 带有javascript的动态xsrf

php - 每月创建表

javascript - 将文本区域符号限制为可见部分

java - 在桌面应用程序和远程服务器之间创建安全连接?

php - 将 N 名员工安置在具有角色的 M 个职位的算法

php - Symfony2 : Problems with function parameter

html - 媒体查询不适应移动浏览器中的布局

javascript - 使用 JQuery 定位隐藏字段

security - 解决方案异常 : Error loading class 'solr.RunExecutableListener' + '/var/tmp/sustes' process

javascript - 使用 .NET 在 SPA 中保护 HTML 和 JS 文件