我正在使用Acunetix测试我的Web应用程序之一.为了保护该项目不受XSS攻击,我使用了HTML Purifier.为此,大多数PHP开发人员都建议使用此库,但是我的扫描结果显示HTML Purifier无法保护我们免受XSS的攻击完全攻击.扫描程序通过发送不同的有害输入来发现两种攻击方式:
> 1< img sRc ='http://attacker-9437/log.php? (请参见HTML Purifier结果here)
> 1“ onm ouseover = vVF3(9185)”(请参阅HTML Purifier结果here)
如您所见,HTML Purifier无法检测到此类攻击.我不知道HTML Purifier上是否有任何特定选项可以解决此类问题,还是真的无法检测到这些XSS攻击方法.
你有什么主意吗?或其他解决方案?
解决方法:
(这是一个较晚的答案,因为此问题已成为重复问题链接到的地方,以前一些重要信息仅在注释中可用.)
HTML Purifier是一种上下文HTML清除器,这就是为什么它似乎在这些任务上失败的原因.
让我们详细了解一下原因:
1< img sRc ='http://attacker-9437/log.php? 您会注意到HTML Purifier为您关闭了此标签,仅保留图像注入.图像是一个完全有效且安全的标签(当然,当前图像库攻击除外).如果希望它完全丢弃图像,请考虑通过设置HTML.Allowed来调整HTML Purifier白名单.
示例中的图像现在正在加载属于攻击者的URL,从而为攻击者提供了加载页面的用户的IP(而没有其他任何东西),这是HTML Purifier并非旨在解决的棘手问题.也就是说,您可以编写HTML Purifier属性检查器,该检查器在纯化之后但在将HTML重新放回之前运行,如下所示:
// a bit of context
$htmlDef = $this->configuration->getHTMLDefinition(true);
$image = $htmlDef->addBlankElement('img');
// HTMLPurifier_AttrTransform_CheckURL is a custom class you've supplied,
// and checks the URL against a white- or blacklist:
$image->attr_transform_post[] = new HTMLPurifier_AttrTransform_CheckURL();
HTMLPurifier_AttrTransform_CheckURL类将需要具有以下结构:
class HTMLPurifier_AttrTransform_CheckURL extends HTMLPurifier_AttrTransform
{
public function transform($attr, $config, $context) {
$destination = $attr['src'];
if (is_malicious($destination)) {
// ^ is_malicious() is something you'd have to write
$this->confiscateAttr($attr, 'src');
}
return $attr;
}
}
当然,很难做到这一点“正确”:
>如果这是通过某些Web服务进行的实时检查,这将使提纯速度缓慢到爬网
>如果您要保留本地缓存,则可能会面临信息过期的风险
>如果您使用启发式(“基于指示符x,y和z,该URL看起来可能是恶意的”),则可能会丢失全部恶意URL类
1 “的onmouseover = vVF3(9185)”
HTML Purifier假定您设置HTML的上下文是< div> (除非您通过设置HTML.Parent另行说明).
如果仅将属性值提供给它,它将假定您将其输出到某个地方,因此最终结果如下所示:
...
<div>1"onmouseover=vVF3(9185)"</div>
...
这就是为什么它似乎对此输入不做任何事情-在这种情况下它是无害的.您甚至可能不想在这种情况下剥离此信息.我的意思是,我们在这里讨论的是*上的这段代码,这很有价值(并且不会引起安全问题).
上下文很重要.现在,如果您改为向HTML Purifier输入以下代码段:
<div class="1"onmouseover=vVF3(9185)"">foo</div>
…突然间您会看到what it’s made to do:
<div class="1">foo</div>
现在将其删除,因为在这种情况下,它本来是恶意的.
HTML Purifier用于什么,不用于什么
因此,现在您不知道要使用HTML Purifier做什么,以及什么时候使用它是错误的工具.这是一个简短的总结:
>如果要输出到HTML文档中,并且对保留HTML完全不感兴趣,则应使用htmlspecialchars($input,ENT_QUOTES,’utf-8′)(或任何编码方式),这是不必要的开销,而且让一些事情通过
>如果要输出到HTML文档并允许格式化,例如,应使用HTML Purifier.如果您是留言板,并且希望人们能够使用HTML格式化消息
>如果要输出到HTML属性(HTML Purifier不是meant for this use-case),则应使用htmlspecialchars($input,ENT_QUOTES,’utf-8′)
您可以找到有关根据上下文in this question / answer进行清理/转义的更多信息.