【编者的话】Dropbox 的 Web 安全防护措施之一是使用基于内容的安全策略(CSP)。Dropbox 的安全工程师 Devdatta Akhawe 通过四篇文章,介绍了 CSP 在 Dropbox 中推广的细节和经验。Dropbox 的 CSP 原则大大减少了 XSS 和内容注入攻击。不过,大规模使用比较严苛的 CSP 规则将面临诸多挑战。我们希望通过这四篇 CSP 系列文章,将 Dropbox 在实践 CSP 过程中的收获分享给广大开发社区朋友。第一篇文章主要介绍如何在规则中设置报表筛选管线来标记错误;第二篇介绍 Dropbox 如何在上述规则中配置随机数及缓解unsafe-inline
带来的安全风险;第三篇介绍如何降低unsafe-eval
造成的风险,以及介绍 Dropbox 所开发的开源补丁;最后一篇介绍在权限分离机制下,如何减小第三方软件整合时的风险。本篇是该系列文章的第一篇,主要讨论 CSP 的报告和过滤机制。
Dropbox 始终坚定地贯彻着 Content Security Policy (CSP)。如果读者对 CSP 规则还不熟悉,我们建议先阅读 Mike West 的《 Excellent Introduction to CSP 》。简单来说,CSP 的核心是一种说明性的机制,它在网页应用中将可靠的内容源(脚本、对象、图像的源等)添加至白名单中。
使用 CSP 限制了内容源,从而降低了网页应用中注入攻击的风险。下面的例子展示了在对 Dropbox 主页发出请求时所使用的 CSP 中的script-src
指令。
script-src https://www.google.com/recaptcha/api/ https://ajax.googleapis.com/ajax/libs/jquery/ https://cf.dropboxstatic.com/static/api/ https://cf.dropboxstatic.com/static/javascript/ https://cf.dropboxstatic.com/static/coffee/compiled/ https://www.dropboxstatic.com/static/javascript/ https://www.dropboxstatic.com/static/coffee/ 'unsafe-eval' 'self' 'unsafe-inline' 'nonce-w+NfAhVZiaXzHT1RmBqS'
指令列出了所有可信赖的 URI(包括浏览器支持的完整路径),通过这些 URI 可以载入所需的脚本代码。当支持 CSP 的网页浏览器检测到了脚本标签,它接下来会检查 src 属性,并和script-src
指令提供的白名单进行对照。如果脚本源不在白名单中(比如,HTML 注入漏洞的原因),浏览器就会阻止请求。
CSP 错误报告过滤器
现在,复杂的网页应用识别和执行 CSP 标头是一个比较困难的问题,不过有一个 CSP 允许的小技巧可以解决这个问题,这便是 report-only 模式。report-only 模式的关键方法是,允许网页测试规则在给制定者选定的终端发送错误报告时的影响。比方说,可以设置一项内容为script-src ‘none’
的 report-only 规则,用来获取所有脚本来源的位置。
report-only 模式大大增强了 CSP 的可行性:首先在 report-only 模式下反复迭代设定的规则,直到没有错误报告,之后转换为执行模式。这一步骤往往是 CSP 进入执行模式前,建议实行的第一步准备工作。在笔者最近参加的一次研讨会中,安全机制专家组着重介绍了 CSP 的 report-only 模式如何可以有效地推广 CSP 的使用,它能够做到某一项规则在使用前就可以评估其效果。
为了获得对已实施规则的有效反馈信息,CSP 的报告功能不可或缺。Dropbox 在转换到 CSP 的“阻塞”模式前,曾经使用 report-only 模式长达数月。但在开始大规模使用 CSP 时,便遇到了第一个问题:报告中的噪声 (sheer noise) 会使得默认报告机制失效。
我们发现,最大的噪声源是浏览器扩展工具。扩展工具在网页中插入了脚本或其他程序可能修改了 HTML,由于 CSP 会阻止网页上运行的所有未知内容,因此注入到网页中的内容很可能也会被浏览器阻止。如果我们仅仅把所有收到的报告加入日志中,那么日志也会包含以上错误。又因为我们无法控制扩展工具,所以也就没有办法做到报告中不添加扩展工具带来的错误信息。
经过一年的 CSP 大规模应用实践,Dropbox 已经完成了一个精确调整的过滤机制,它可以忽略一般的误报。我们的报告管线筛选掉误报的报告内容,然后才将有效的报告加入分析处理后台。本着推广 CSP 的精神,Dropbox 将这个过滤器技术分享出来,希望其他开发者可以使用。我们强烈建议读者阅读 Neil Matatall 这篇介绍精准 CSP 列表的文章,实际上我们使用的列表也参考了文章中涉及的技术。
初看起来,筛选错误报告似乎有些奇怪,为什么不想知道广告插入和网页垃圾什么时候修改了网页应用呢?但是在这里,我们讨论的是 CSP 的预使用阶段,主要关注点是 CSP 的内容白名单不会使网页应用崩溃。滤除报告中的噪声,保证了 CSP 执行时对网页应用进行合理的修改。一旦转换到 CSP 执行模式,浏览器将根据过滤后的报告进行阻止操作。
过滤器是双重结构。第一层过滤基于被阻止的 URI。
_ignored_blockedURI_schemas = [ "http:",# We never use HTTP content so not a legit report "mxaddon-pkg",# maxthon addon packages "jar:",# firefox addons "file:",#we never insert file URIs into the page "tmtbff://",# ticketmaster toolbar? "safari",# safari extensions "chrome",# stuff like chromenull: chrome:// chrome-extension:// "webviewprogressproxy:",# added by browsers in webviews "mbinit:",# MapBuilder "symres:",# Norton "resource", ];
如果被阻止的 URI 以列表中任何一项开头,则忽略。第二层过滤基于被阻止 URI 的主体部分。
_ignored_blockedURI_hosts=[ "tlscdn", ".superfish.com", "addons.mozilla.org", "v.zilionfast.in", "widgets.amung.us", "xls.searchfun.in", "static.image2play.com", "localhost", "127.0.0.1", "guzzlepraxiscommune", "tfxiq", "akamaihd.net", #Dropbox doesn't use Akamai CDN "apollocdn", "worldssl.net", "shwcdn.net", "cmptch.com", "datafastguru.info", "eshopcomp.com", "hwcdn.net", ]
如果被阻止 URI 的主体部分包含上面的任何一个关键词,过滤器代码都不会将错误报告加入日志。当然,在使用该列表之前,必须保证在自己的网站中,没有使用列表中的任何一个域名。
修改 CSP 规则的扩展工具是另外一个噪声源。为了忽略这类错误,过滤器的设计同样也是基于违反的指令字段 (violated directive field)。如果违反的指令字段包含“http:”或“:443”,报告将进行滤除,因为在规则中并不包含这些内容。为了做到这一点,我们考虑使用的一个方法是,在报告的 URI 中添加当前规则的 hash 表,之后只接受错误报告中的规则符合 URI 中 hash 表的报告。但是目前我们还没有将这种方法付诸实践。
查看英文原文: [CSP] On Reporting and Filtering
编后语
《他山之石》是 InfoQ 中文站新推出的一个专栏,精选来自国内外技术社区和个人博客上的技术文章,让更多的读者朋友受益,本栏目转载的内容都经过原作者授权。文章推荐可以发送邮件到 editors@cn.infoq.com。
感谢魏星对本文的审校。
给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ , @丁晓昀),微信(微信号: InfoQChina )关注我们,并与我们的编辑和其他读者朋友交流(欢迎加入 InfoQ 读者交流群(已满),InfoQ 读者交流群(#2))。
评论