Packagist.org远程代码执行漏洞分析

本文披露了PHP包管理器Composer的默认包服务器packagist.org存在的远程代码执行漏洞,攻击者可通过在文本字段注入$(command)实现命令执行,该漏洞影响月下载量达4亿次的服务。

Packagist.org远程代码执行漏洞

作者:Max Justicz
日期:2018年8月28日

摘要

packagist.org(PHP包管理器Composer的默认包服务器)存在远程代码执行漏洞。Packagist目前每月服务约4亿次包下载量。虽然该漏洞在技术上并不复杂,但由于Packagist是热门服务且是“PHP包管理器”的顶级谷歌搜索结果,值得公开讨论。

漏洞详情

用户可以在网站的大文本字段中输入$(执行命令),该命令会在shell中执行(两次)。

漏洞原理

用户通过提供Git、Perforce、Subversion或Mercurial仓库的URL来上传包到Packagist。为了识别URL指向的仓库类型,Packagist会调用git、p4、svn和hg,使用包含该URL作为参数的应用特定命令。

通过检测执行shell命令的方法ProcessExecutor::execute,发现对于URL$(sleep 1),会运行以下命令:

1
2
3
4
git ls-remote --heads '$(sleep 1)'
hg identify '$(sleep 1)'
p4 -p $(sleep 1) info -s
svn info --non-interactive $(sleep 1)

其中,p4和svn包装器未正确转义URL参数。

修复措施

Packagist团队通过转义Composer仓库中的相关参数快速解决了此问题。漏洞已报告至security@packagist.org。

结论

包管理器安全性通常不够完善,应假设包管理器服务器未来可能被入侵。

过去一年左右,我发现了一些漏洞,允许在rubygems.org上执行任意代码、在npm的一些官方镜像(非主注册表)上执行代码、从PyPI删除任意发布文件、在使用npm流行CDN的每个网站上提供任意JS,以及现在在packagist.org上执行任意代码。其他人也发现了类似漏洞。这还不包括合法包被入侵的风险。

特别需要注意的是,如果包不预期更改,让应用构建管道在每次构建时从上游服务器拉取新下载的包是一种安全反模式。如果必须这样做,应使用加密安全哈希函数固定依赖项。


联系信息:
Max Justicz
max@justi.cz
mastodon.mit.edu/@maxj

本博客会仅几篇文章后就放弃吗?敬请关注!

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计