AngularJS的伏击:Piwik PRO中隐藏的CSP绕过
任何网站组件都可能破坏整个站点的安全性,分析平台也不例外。基于此,我们决定快速审计Piwik PRO,确保其可安全部署在portswigger.net上。我专注于寻找DOM XSS等客户端问题,因为我们引入了新的脚本资源,最可能的攻击向量便是DOM XSS漏洞。
首先,我启用DOM Invader浏览站点并尝试注入canary(测试字符串)——未获结果,这是好消息。接着,我将DOM Invader的canary改为空值,从而查看所有使用的sink(代码执行点),无论canary是否存在。这对发现document.write()等非常有用,果然存在document.write调用和多个innerHTML赋值。我获取堆栈跟踪并检查document.write()调用,注意到有一个debug标志…这引出了我的下一个问题:这有什么用?
我将该标志添加到URL中,果然出现了分析调试器。我测试了document.write调用是否易受XSS攻击,然后思考下一个问题:这个调试器是如何构建的?我开始使用devtools检查调试器,立即注意到"ng-app"事件。中奖了,这是我的老朋友AngularJS。
您可能好奇为什么我这么兴奋。这是因为AngularJS有众所周知的脚本gadget,可用于绕过Content Security Policy(CSP)。脚本gadget是一些JavaScript代码,通常来自库,为HTML或JavaScript添加额外功能。然后您可以利用此gadget绕过CSP,因为gadget已有JavaScript执行权限且被策略允许。AngularJS中的ng-focus就是一个好例子——该事件让您执行浏览器focus事件,但由于ng-focus是非标准的,它将被CSP允许并由AngularJS自身执行。
一旦确定存在AngularJS gadget,有两种可能结果:执行客户端模板注入(CSTI),或实现CSP绕过。CSTI不可能,因为它需要HTML注入漏洞来注入脚本资源。剩下的是CSP绕过,这很重要需修复,因为如果站点有HTML注入漏洞,攻击者可用CSP绕过升级到XSS。我过去曾在PayPal中发现此类XSS。
进一步检查中,调试器似乎使用iframe并加载了CSP允许的各种脚本资源。我参考了XSS cheat sheet以查看AngularJS的各种CSP绕过方法。我选择了第一个,并在控制台中输入以下内容:
|
|
果然,这完全绕过了CSP。因为脚本被允许列出,攻击者可注入AngularJS指令和ng-focus事件,使用composedPath()获取窗口对象数组。orderBy过滤器遍历该数组和执行代码的作用域,最终成为窗口对象,Array.from()用于间接调用alert函数——从而绕过CSP。我们向Piwik报告了此问题,他们更新了CSP部署说明以解决此漏洞。他们通过收紧CSP以允许列出特定JavaScript文件而非整个域来修复问题,还对某些脚本使用nonce,这防止了攻击者注入自己的AngularJS脚本资源。
此修复已生效——如果您发现我们遗漏的内容,请报告给PortSwigger和Piwik PRO的漏洞赏金计划。
时间线
- 2023年3月2日 10:51 - 向Piwik报告CSP绕过
- 2023年3月2日 11:20 - Piwik确认收到
- 2023年3月3日 13:09 - 漏洞确认
- 2023年3月7日 12:24 - CSP部署说明更新以修复漏洞
- 2023年4月28日 13:00 - 博客文章发布