【技术分享】如何使用CSP Auditor配置高效的内容安全策略

http://p4.qhimg.com/t01aefee730a992322f.png

译者:WisFree

预估稿费:180RMB

投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿


写在前面的话

在浏览器与跨站脚本漏洞(XSS)的抗争过程中,内容安全策略(即Content Security Policy,简称CSP)的出现绝对是具有里程碑式意义的。由于内容安全策略的存在,我们能依靠的不仅仅只是浏览器的反XSS过滤器了,我们现在将有可能通过浏览器来对类似JavaScript这样的外部资源进行额外的限制(可以通过CSP HTTP头来强制实现)。但是在CSP配置自动生成机制嵌入到Web框架之前,这种技术还很难成为一种实践标准。就目前的情况来看,绝大多数情况下仍然需要开发人员手动配置Web应用程序的内容安全策略。

在这篇文章中,我们将跟大家讨论关于如何将内容安全策略整合到现有网站中的一些基本策略。除此之外,我们还会介绍CSP Auditor的最新功能以及相关的理论知识。如果你对内容安全策略或者CSP Auditor不够了解的话,我建议大家先阅读我们之前所发表的这篇文章


CSP Auditor

该插件提供了以下几种功能:

1.在Response标签下提供了可视化的CSP Header;

2.采用了被动扫描规则来检测存在安全漏洞的CSP配置;

3.基于Burp crawler或手动浏览实现了一个CSP配置生成器;

注:该项目以ZAP和Burp插件的形式进行封装。


工具下载

最新版本:201783日更新

Burp插件:点我下载

ZAP插件:点我下载

CSP Auditor:GitHub项目主页

你可以使用以下命令构建CSP Auditor插件:

./gradlew build

如果你已经安装了Gradle,那你可以选择使用下列命令:

gradle build

如何配置出高效的内容安全策略

如果你想配置出有效的内容安全策略,你可以先考虑以下三种最基本的因素:

1.针对外部资源采用白名单机制,这里的外部资源可以是CSS样式、图片或JavaScript代码;

2.识别内联脚本标签;

3.替换内联脚本事件;

针对外部资源采用白名单机制

这一步可以算是实现起来最简单的一步了,这一步需要对Web应用程序所使用的JavaScript、图片以及CSS样式表进行分析和识别。只有托管在外部域名的文件以及资源才需要被添加到内容安全策略的配置之中。

<script src="//cdn.myprovider.com"></script>
<img src="https://staticimages.com/img/870234324.png">
<link rel="stylesheet" type="text/css" href="https://cdn.company.com/mystyle.css">

上面给出的这些资源将会被转译成下面这种CSP HTTP头,内容如下所示:

default self; script-src cdn.myprovider.com; image-src https://staticimages.com; style-src https://cdn.company.com;

CSP Auditor中,我们可以通过两种方法来列出所有的外部资源。在"External Resources"(外部资源)标签下,我们可以看到所有已选择域名所加载的全部资源。外部资源视图如下:

http://p4.qhimg.com/t015829e5bf1b4573ca.png

在"Configuration"(配置)标签下,你可以对所有托管了外部资源的域名进行配置,并设置一份CSP配置草案。注:列表内容会根据目标网站的分析结果进行自动填充。配置视图如下:

http://p3.qhimg.com/t01ea0e25661c3c3745.png

为了让内容安全策略尽可能地覆盖你网站所加载的全部资源,你需要使用网络爬虫(例如Burp crawler)或其他手动的爬取方法来尽可能多地爬取你的网站页面。一般来说,开发人员通常都会在Web应用程序的主页(Home page)中导入绝大多数的资源,即便是这个页面不需要使用的资源也有可能会加载进去,因为这样做可以尽早地对资源进行缓存,而且还可以简化之后的页面开发。这样一来,我们大多数情况下只用访问几个页面就能收集到网站加载的绝大多数资源了。


识别内联脚本标签

刚才介绍的第一步操作应该还是比较容易完成的。但是相对来说,控制内联脚本还是比较困难的。在我们的分析场景中,需要对HTML页面做以下修改:

<script>function example() {..}</script>

正如上面这段代码所示,内容安全策略的默认模式下是不允许内联脚本的,而这样做的目的是为了防止攻击者通过XSS攻击向量在Web应用程序中嵌入恶意脚本代码。目前主要有两种方式来防止内联脚本,第一种方法是将脚本代码移动到一个单独的JavaScript文件中,而不是像之前一样直接把脚本代码嵌入在HTML页面之中。

<script src="/new-script.js"></script>

另一种方法是在脚本块中添加一个随机数(nonce)。这种方法需要生成一个随机令牌并存放在header中,然后在每一个脚本块中添加一个nonce属性并填充随机数值。

Content-Security-Policy: script-src 'self' 'nonce-9135759873587943987538793';
 
[…]
<script nonce="9135759873587943987538793">function example() {..}</script>

除了上述这些内联脚本之外,还有一个我们目前还没介绍的变种版本的内联脚本:DOM on-events handlers(一种HTML属性)。跟内联脚本标签一样,我们需要找出每一个相关属性并完成修改替换。下面给出的是一个简单示例:

原始的HTML:

<input type="button" id="btn_example" onclick="alert('code triggered');" value="Click Me!">

修改后的HTML

<script src="/site-event-bundle.js"></script>
<input id="btn_example" type="button" value="Click Me!" />

JavaScript (/site-event-bundle.js)

document.getElementById('btn_example').onclick = function() {alert('code triggered')};

替换内联脚本事件

由于内联脚本在Web应用程序中几乎是随处可见的,因此这些内联脚本的数量对我们来说会是一个很大的麻烦。为了确认我们需要修改的内联脚本数量,我们可以在"Inline Scripts"视图中查看到工具对Web流量的分析结果。下面给出的是内联脚本视图:

http://p5.qhimg.com/t011eaea6caf7658107.png


总结

在这篇文章中,我们给大家介绍了三种部署内容安全策略的方案。但不幸的是,针对传统网站目前还没有一种通用的缓解方案。因此,我们希望CSP Auditor插件的这些新功能可以帮助广大开发人员更好地将新型的安全Header整合到自己的Web应用程序中以提升安全性。

如果目标网站中不存在跨站脚本漏洞,或者说其中的跨站脚本漏洞不足以影响网站安全性的话,添加额外的CSP Header可能并不会产生非常好的效果。你可以通过查看"External Resources"以及"Inline Scripts"视图下的内容来评估部署内容安全策略的工作量。

最后来一波预告:我们目前仍然在优化CSP Auditor,希望对该项目感兴趣的用户可以帮助我们一起提升CSP Auditor。最终的解决方案将适用于所有的WordPress站点。


参考资料

1.CSP配置命令表:https://content-security-policy.com/

2.内联脚本缓解样例:http://www.cspplayground.com/compliant_examples

3.使用Burp和ZAP审计CSP Header:https://gosecure.net/2016/06/28/auditing-csp-headers-with-burp-and-zap/

4.CSP Auditor项目地址:https://github.com/GoSecure/csp-auditor

(完)