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 处理之前的源代码完全相同。
我在我的项目中使用 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 处理之前的源代码完全相同。