通过CDN漏洞攻陷数千个网站
Max Justicz
2018年5月23日
摘要:unpkg.com是一个流行的CDN服务,用于托管npm包资源。我在其tar解压实现中发现了一个漏洞,允许攻击者在服务器上写入任意文件(包括其他包的文件)。若被利用,此漏洞可使攻击者在数千个网站(包括PNC银行、React.js主页和内布拉斯加州政府网站)上执行恶意JavaScript。切勿完全信任第三方CDN——请使用子资源完整性(SRI)和哈希锁定!
漏洞详情
当用户请求类似https://unpkg.com/react@16.3.2/
的URL时,unpkg会检查是否已在/tmp/unpkg-react-16.3.2/
目录下下载并解压该包。若未找到,则从npm拉取对应的tar文件。
解压后,unpkg允许读取包内的任何文件。例如,访问https://unpkg.com/react@16.3.2/package.json
可获取react的package.json文件,而访问https://unpkg.com/react@16.3.2/
则可查看整个包的目录列表。
以下是unpkg用于解压tar文件的代码片段:
|
|
此代码的第一个问题是:它并未如声称的那样忽略符号链接。在该tar库中,符号链接条目的header.type
为symlink
而非link
。因此,攻击者可通过创建指向/
的符号链接,并利用Web界面浏览目录,实现服务器上的任意文件读取。
第二个问题是:即使headers.type
正确检查了symlink
,由于tar库的ignore函数实现问题,下述主要攻击仍可生效。
首次漏洞利用尝试
在本地unpkg实例上,我利用此漏洞读取了/proc/self/environ
,该文件会输出Web服务器进程的环境变量。这些变量中包含一个Cloudflare API密钥,攻击者可能利用其通过API进行恶意DNS操作(此为未经测试的假设——我不确定Cloudflare是否支持限制API密钥权限)。
不幸的是(或幸运的是?),Heroku环境的某些特性导致我无法在真实unpkg服务器上读取/proc/self/environ
。推测原因与服务器返回的错误HTTP Content-Length有关:读取/proc/self/environ
时,本地实例报告Content-Length: 0
,但仍返回了文件内容。Heroku的智能反向代理可能检测到Content-Length: 0
并截断了响应体。
服务器返回Content-Length: 0
是因为stat /proc/self/environ
返回大小为0,而unpkg使用此值设置该头部。
第二次漏洞利用尝试
此时我因未能找到接管服务器的方法而略显沮丧。我向unpkg维护者报告了符号链接问题后便休息了。
但随后我开始深入思考tar文件:我们能解压文件到文件夹、创建符号链接……能否将文件解压到已提取的符号链接所指向的目录?我使用十六进制编辑器制作了一个tar文件,尝试创建指向/tmp
的符号链接link
,然后尝试将文件解压到link/oops.txt
。
我原以为任何成熟的tar实现都不会允许此操作,果然在笔记本电脑上解压失败:
|
|
但unpkg未使用GNU Tar,而是使用了名为tar-fs
的包。而tar-fs
愉快地解压了此归档文件。
于是我们成功了!由于我们能在Web服务器用户权限范围内写入(和覆盖)任意文件,我们可以覆盖其他包专用目录中的文件(如/tmp/unpkg-react-16.3.2/
)。为测试此漏洞,我制作了一个包的两个版本,并让第二个版本覆盖第一个版本的文件(测试成功)。
比预期更严重的漏洞
许多tar实现还支持解压硬链接。由于创建指向目录的硬链接通常是无效操作,我制作了原始漏洞利用的变体:
- 创建指向已知存在文件的硬链接
foo
- 解压名为
foo
的常规文件(内容任意)
果然,tar-fs
对此攻击同样脆弱,只要我有适当权限且知道文件在文件系统中的位置,就能覆盖文件。
向tar-fs
维护者报告此变体后,他次日早晨回复时显得有些担忧。出乎意料的是,更流行的tar库node-tar
也对硬链接变体脆弱。tar-fs
维护者与我提交了错误报告,node-tar
也迅速打了补丁。
哦,如果你需要一个深度防御的教科书案例,请记住:npm客户端(使用pacote因而依赖node-tar)未受此攻击影响,唯一原因是pacote开发者有先见之明,决定从不解压硬链接或软链接。
结论
如果你的JavaScript CDN开始提供恶意软件,你和你的用户会多惨?完全沦陷?因此,请自行托管文件或使用子资源完整性(SRI)。它允许你锁定要加载文件的加密哈希,在现代浏览器中防范此类攻击。
感谢unpkg.com、tar-fs和node-tar的维护者快速修复这些漏洞。
无耻推广:如果你厌倦了#鸟类网站并想使用真正尊重自由的社交网络,应考虑加入Mastodon!这是一个联邦式社交网络,其分布式工作原理类似电子邮件。加入联邦宇宙(fediverse),帮助我们构建友好的安全社区!
联系信息
Max Justicz
max@justi.cz
mastodon.mit.edu/@maxj
我会在仅几篇文章后放弃此博客吗?敬请关注!