PHP Composer漏洞可能引发供应链攻击

2025-05-27 0 79

Composer是PHP中管理和安全软件依赖的主要工具,被开发团队广泛应用于更新过程等。因此,Composer使用名为Packagist 的在线服务来确定包下载供应链的正确性。而Packagist每个月的下载请求在14亿次左右。

PHP Composer漏洞可能引发供应链攻击

研究人员在进行安全研究时,在 Packagist使用的Composer源码中发现了一个严重的安全漏洞漏洞CVE编号为CVE-2021-29472。攻击者利用该漏洞可以在Packagist.org 服务器上执行任意系统命令。此外,攻击者还可以进一步窃取维护者凭证,或将包下载重定向到传播后门依赖的第三方服务器。

漏洞分析

在请求下载包时,Composer 首先会查询Packagist来获取元数据。元数据中包含2个获取代码源的域source和dist。Source只想开发库,dist只想预构建的库。Composer在从库中下载代码时会使用外部系统命令来避免重新实现针对每隔版本控制软件的逻辑。因此,这些调用都是用wrapper ProcessExecutor来执行的:

  1. composer/src/Composer/Util/ProcessExecutor.php
  2. useSymfony\\Component\\Process\\Process;
  3. //[…]
  4. classProcessExecutor
  5. {
  6. //[…]
  7. publicfunctionexecute($command,&$output=null,$cwd=null)
  8. {
  9. if(func_num_args()>1){
  10. return$this->doExecute($command,$cwd,false,$output);
  11. }
  12. return$this->doExecute($command,$cwd,false);
  13. }
  14. //[…]
  15. privatefunctiondoExecute($command,$cwd,$tty,&$output=null)
  16. {
  17. //[…]
  18. if(method_exists('Symfony\\Component\\Process\\Process','fromShellCommandline')){
  19. //[1]
  20. $process=Process::fromShellCommandline($command,$cwd,null,null,static::getTimeout());
  21. }else{
  22. //[2]
  23. $process=newProcess($command,$cwd,null,null,static::getTimeout());
  24. }
  25. if(!Platform::isWindows()&&$tty){
  26. try{
  27. $process->setTty(true);
  28. }catch(RuntimeException$e){
  29. //ignoreTTYenablingerrors
  30. }
  31. }
  32. $callback=is_callable($output)?$output:array($this,'outputHandler');
  33. $process->run($callback);

在 [1]和[2]中,可以看到参数 $command 是在shell中执行的。大多数的ProcessExecutor 调用都是在版本控制软件驱动中执行的,版本控制软件负载原创和本地库的所有操作。比如,在Git驱动中:

  1. composer/src/Composer/Repository/Vcs/GitDriver.php
  2. publicstaticfunctionsupports(IOInterface$io,Config$config,$url,$deep=false)
  3. {
  4. if(preg_match('#(^git://|\\.git/?$|git(?:olite)?@|//git\\.|//github.com/)#i',$url)){
  5. returntrue;
  6. }
  7. //[…]
  8. try{
  9. $gitUtil->runCommand(function($url){
  10. return'gitls-remote–heads'.ProcessExecutor::escape($url);//[1]
  11. },$url,sys_get_temp_dir());
  12. }catch(\\RuntimeException$e){
  13. returnfalse;
  14. }

使用ProcessExecutor::escape() 可以将参数$url 逃逸以预防子命令($(…), `…`) ,但是无法预防用户提供(–)开头的值,只要加上其他的参数就可以成为最终的命令。这类漏洞就叫做参数注入。

类似的有漏洞的模式也出现在其他驱动中,用户控制的数据可以成功绕过检查并连接在一起成为系统命令:

  1. composer/src/Composer/Repository/Vcs/SvnDriver.php
  2. publicstaticfunctionsupports(IOInterface$io,Config$config,$url,$deep=false)
  3. {
  4. $url=self::normalizeUrl($url);
  5. if(preg_match('#(^svn://|^svn\\+ssh://|svn\\.)#i',$url)){
  6. returntrue;
  7. }
  8. //[…]
  9. $process=newProcessExecutor($io);
  10. $exit=$process->execute(
  11. "svninfo–non-interactive".ProcessExecutor::escape($url),
  12. $ignoredOutput
  13. );
  14. composer/src/Composer/Repository/Vcs/HgDriver.php
  15. publicstaticfunctionsupports(IOInterface$io,Config$config,$url,$deep=false)
  16. {
  17. if(preg_match('#(^(?:https?|ssh)://(?:[^@]+@)?bitbucket.org|https://(?:.*?)\\.kilnhg.com)#i',$url)){
  18. returntrue;
  19. }
  20. //[…]
  21. $process=newProcessExecutor($io);
  22. $exit=$process->execute(sprintf('hgidentify%s',ProcessExecutor::escape($url)),$ignored);
  23. return$exit===0;
  24. }

更多技术细节参见:https://blog.sonarsource.com/php-supply-chain-attack-on-composer

补丁

研究人员将该漏洞提交给Packagist团队后,该团队快速反应,在12个小时内就部署了安全补丁。

本文翻译自:https://blog.sonarsource.com/php-supply-chain-attack-on-composer

原文链接:https://www.4hou.com/posts/m8PG

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 PHP Composer漏洞可能引发供应链攻击 https://www.kuaiidc.com/72231.html

相关文章

发表评论
暂无评论