HTML Purifier - 转义不允许的标签而不是剥离

HTML Purifier - Escape disallowed tags instead of stripping

我正在使用 HTML Purifier 来净化用户输入。我有一个配置的允许元素列表,这意味着不在允许列表中的任何标记都将被删除。代码如下:

require_once "HTMLPurifier.standalone.php";
$config = HTMLPurifier_Config::createDefault();
$config->set('HTML.AllowedElements', array('strong','b','em','i'));
$purifier = new HTMLPurifier($config);
$safe_html = $purifier->purify($dirty_html));

与其只保留它们的内容,我希望对列表中未包含的元素进行转义并作为文本发回。


为了说明,给定上面显示的白名单,输入以下字符串:

<a href="javascript:alert('XSS')"><strong>CLAIM YOUR PRIZE</strong></a>

变成"<strong>CLAIM YOUR PRIZE</strong>",因为a不在白名单中。同样,

<b>Check the article <a href="http://example.com/">here</a></b>

变成"<b>Check the article here</b>".

有没有办法把上面两个例子变成下面这样:

&lt;a href="javascript:alert('XSS')"&gt;<strong>CLAIM YOUR PRIZE</strong>&lt;/a&gt;
<b>Check the article &lt;a href="http://example.com/"&gt;here&lt;/a&gt;</b>

纯粹通过调整HTML净化器的配置而不诉诸基于正则表达式的"hacks"?如果有,那我想知道是怎么做到的。

设置 Core.EscapeInvalidTags 应该是您要找的:

require_once(__DIR__ . '/library/HTMLPurifier.auto.php');

$dirty_html = '<a href="javascript:alert(\'XSS\')"><strong>CLAIM YOUR PRIZE<div></div></strong></a>';

$config = HTMLPurifier_Config::createDefault();
$config->set('HTML.AllowedElements', array('strong','b','em','i'));
$config->set('Core.EscapeInvalidTags', true);
$purifier = new HTMLPurifier($config);
$safe_html = $purifier->purify($dirty_html);

echo $safe_html . PHP_EOL;

...给出:

&lt;a href="javascript:alert('XSS')"&gt;<strong>CLAIM YOUR PRIZE&lt;div /&gt;</strong>&lt;/a&gt;

我在那里放入了无效的子元素 <div></div> 这样你就可以看到发生了什么:HTML Purifier 仍然会 'alter' 原始的 HTML 由于解析它 ( <div></div> 变为 <div />),但信息保留(并转换为 &lt;div /&gt;)。