我正在使用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>"
。
有没有办法将以上两个例子变成以下内容:
<a href="javascript:alert('XSS')"><strong>CLAIM YOUR PRIZE</strong></a>
<b>Check the article <a href="http://example.com/">here</a></b>
纯粹是通过调整HTML Purifier的配置而不诉诸基于正则表达式的“hacks”?如果有,那么我想知道它是如何完成的。
答案 0 :(得分:2)
设置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;
...给出:
<a href="javascript:alert('XSS')"><strong>CLAIM YOUR PRIZE<div /></strong></a>
我在那里投入了无效的子元素<div></div>
,这样你就可以看到会发生什么:由于解析它,HTML Purifier仍会“改变”原始HTML(<div></div>
变为<div />
) ,但信息仍然存在(并转换为<div />
)。