Composer Cache Injection vulnerability - CVE-2015-8371

End of last year I analyzed composer for a few attack vectors, which make use of Packagist to target Projects with own Repositories.

Surprisingly I found one Vector, which still produces a danger, even if you disable the default packagist repository for your project.

The Vulnerability was fixed on 10.02.2016 in the source of composer.

The source of the problem lies in the way composer cached dist packages. The Cache Key was generated from the name of the package, the dist type, and a “magical” reference, which got provided from the package repository (packagist uses the commit hash here) and is easy to fake.

There are two easy ways to make use of this.
The first one is directly via packagist, to add the package you want to use for the attack, and which before only exists on the project specific repository yet. And as cached packages have a ttl of 30 days, they will even after removing them from the repository stay inside the cache for a while.

The second one is more interesting as it is easy to get people to install a new hip composer project. I talk about the composer package type “project”, as it allows some additional stuff, like usage of own repositories, or even to directly define dist packages. So you can even replace packages, existing on packagist.
A likely target then would be the symfony/console package, which is used by a lot of projects.

The evil thing about this attack is, it would even work when you disable plugins and scripts for this run. And making use of this options should normally remove every potential security thread.
Btw. you should always disable both for new projects and packages you want to try out or only looking at.

How would such an evil project look:

json { "name": "evil/project", "type": "project", "version": "2.0.0", "repositories": [ { "type": "package", "package": { "name": "symfony/console", "version": "v2.7.6", "dist": { "url": "", "reference": "5efd632294c8320ea52492db22292ff853a43766", "type": "zip" } } } ], "require": { "symfony/console": "v2.7.6" } }

For extra evil you can add a post-root-package-install script to clean the cache, as not everyone disables scripts.

Anyway, the attack would only work when the package is not already cached, but having success in only one of 31 cases should be enough for a package which has 40k daily installs. And one success allows for more evil stuff to spread maleware into the developers ecosystem. Just imagine a global git hook, which modifies pushes to github into non PR branches.