HTML 净化器 - iframe 和脚本

HTML Purifier - iframe and scripts

我在我的项目中使用 HTML Purifier

我的html是这样的。 (包含简单的html元素+脚本+iframe)

<p>content...<p>
<iframe></iframe>
<script>alert('abc');</script>
<p>content2</p>

默认配置下变成这样

<p>content...</p>
<p></p>
<p>Content2</p>

但是如果我这样设置配置...

$config->set('HTML.Trusted', true);
$config->set('HTML.SafeIframe', true);

我知道了

<p>content...</p>
<p>
    <iframe></iframe>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    alert('abc');
    //--><!]]></script>
</p>
<p>content2</p>

有没有办法使用HTML净化器完全去除'script'标签但保留'iframe'标签?或者 HTML 净化器的其他替代品?

我试过了

$config->set('Filter.YouTube', true);
$config->set('URI.SafeIframeRegexp', '%^https://(www.youtube.com/embed/|player.vimeo.com/video/)%');

但结果 'script' 标签仍​​然存在。

[已编辑]

完整示例。

$config = HTMLPurifier_Config::createDefault();

$html = "<p>content...<p><iframe ...></iframe><script>alert('abc');</script><p>content2</p>";

$config->set(
        'HTML.ForbiddenElements',
        'script'
    );

$purifier = new HTMLPurifier($config);

$clean_html = $purifier->purify($html);

结果

<p>content...</p><p></p><p>content2</p>

你已经走对了一半。如果您将 HTML.SafeIframe to true and URI.SafeIframeRegexp 设置为您要接受的 URL(%^https://(www.youtube.com/embed/|player.vimeo.com/video/)% 工作正常),输入示例:

<p>content...<p>
<iframe src="https://www.youtube.com/embed/blep"></iframe>
<script>alert('abc');</script>
<p>content2</p>

...变成...

<p>content...</p><p>
<iframe src="https://www.youtube.com/embed/blep"></iframe>

</p><p>content2</p>

解释HTML.SafeIframe 允许 <iframe> 标签,但 HTML Purifier 仍然需要 iframe 可以包含的 URL 的白名单,否则 <iframe> 会打开太多的恶意潜力。 URI.SafeIframeRegexp 提供白名单(以需要匹配的正则表达式的形式)。

看看是否适合你!

代码

这是进行我刚才提到的转换的代码:

$dirty = '<p>content...<p>
<iframe src="https://www.youtube.com/embed/blep"></iframe>
<script>alert(\'abc\');</script>
<p>content2</p>';

$config = HTMLPurifier_Config::createDefault();
$config->set('HTML.SafeIframe', true);
$config->set('URI.SafeIframeRegexp', '%^https://(www.youtube.com/embed/|player.vimeo.com/video/)%');

$purifier = new HTMLPurifier($config);

$clean = $purifier->purify($dirty);

关于HTML.Trusted

如果您不完全信任每一位提交 HTML 的人,我恳请您永远不要将 HTML.Trusted 设置为 true

除其他外,它允许您输入的表单 HTML 在净化过程中不受干扰地存活下来,这(如果您正在为网站进行净化,我假设您是)使网络钓鱼攻击变得微不足道。它允许您的输入使用毫发无损的样式标签。它仍然会去除一些东西(HTML Purifier 实际上不知道的任何 HTML 标签,即大多数 HTML5 个标签是其中的一些,各种 JavaScript 属性处理程序),但是有足够多的攻击媒介,如果您使用此指令,您可能还不如不进行净化。作为 Ambush Commander once put it:

You shouldn't be using %HTML.Trusted anyway; it really ought to be named %HTML.Unsafe or something.

考虑使用像 Masterminds html5-php 这样成熟的 HTML 解析器。 HTML 代码将被解析而不会进行不需要的更改,例如将 IFRAME 包装在 P 中,您将能够按照您想要的方式操作生成的 DOM 树,包括删除一些元素同时保留其他元素。

例如,以下代码可用于从文档中删除 SCRIPT 个元素:

foreach ($dom->getElementsByTagName('script') as $script) {
    $script->parentNode->removeChild($script);
}

并注意这样的代码:

<script type="text/javascript"><!--//--><![CDATA[//><!--
    alert('abc');
//--><!]]></script>`

已过时。现代 HTML5 等效代码是:

<script>alert('abc');</script>

与 HTML Purifier 处理之前的源代码完全相同。