Packagist is the default package host behind Composer, it has over 435 million package installs.
The vulnerability was reported by the security researcher Max Justicz, the expert discovered that the “Submit Package” input field for submitting new PHP packages via the package repository homepage allowed an attacker to execute a malicious command in the format of “$(execute me)”.
“You could type $(execute me) into a big text field on the site and it would execute your command in a shell (twice).” reads the security advisory published by the expert.
“You upload packages to Packagist by providing a URL to a Git, Perforce, Subversion, or Mercurial repository. To identify what kind of repository the URL points to, Packagist shells out to git, p4, svn, and hg, with application-specific commands that include this URL as an argument,”
The expert pointed out that when a user provided an URL to Packagist it was improperly escaping the input allowing ill-intentioned to execute any commands in a shell (twice).
The mitigation was simple, the maintainers of the Packagist repository simply implemented the escaping functionality for the relevant parameters in the Composer repository.
“The Packagist team quickly resolved this issue by escaping the relevant parameters in the Composer repository,” explained Justicz.
The expert warned of the low level of security implemented for the Package manager that could open the doors to future attacks.
“Package manager security is not always great, and you should probably plan on your package manager servers being compromised in the future. In the past year or so I have found bugs that let me execute arbitrary code on rubygems.org, execute code on some of npm’s official mirrors (not the main registry), delete arbitrary release files from PyPI, serve arbitrary JS on every site using a popular CDN for npm, and now execute arbitrary code on packagist.org.” concludes the expert.
“I think it is a security anti-pattern to have application build pipelines pull fresh downloads of packages from upstream servers on every build if the packages are not expected to change. If for some reason you have to do this, you should pin dependencies using a cryptographically secure hash function.”