Package registry vulnerable to manifest confusion
Summary
Based on the results of an ongoing AppSec review on a newly researched vulnerability termed manifest confusion, it was found that our own NPM package registry is vulnerable to this behaviour.
Using the NPM API, it is possible to upload a package with 2 conflicting package data. One inside the JSON body (aka manifest data) sent to the API endpoint, and another one in the package.json
of the actual package.
A few examples of vulnerabilities taken from the blogpost:
Executes install scripts not present in manifest
No scripts can be viewed in the manifest data for the following package https://gitlab.com/api/v4/projects/40775931/packages/npm/@ameyetest/mypkg-install-script. However, when running npm install
, the installation script is executed:
Yarn usage can lead to a potential downgrade attack of the dependency
I created 2 packages at https://gitlab.com/api/v4/projects/40775931/packages/npm/@ameyetest/mypkg-downgrade-version, one with genuine contents v1.0.0, and another v1.1.0 which has the version set to v1.0.0 in package.json
. Using yarn add @ameyetest/mypkg-downgrade-version@1.1.0
in a project adds the v1.0.0 version in the lockfile as well as the package.json for that project. Any subsequent operations like upgrade or install will now downgrade the v1.1.0 dependency to v1.0.0.
Consequently, most of the bugs listed at https://blog.vlt.sh/blog/the-massive-hole-in-the-npm-ecosystem also apply to our own package registry, which relies on the manifest supplied data, where as the package managers rely on the package.json
file for most of their commands.
What is the current bug behavior?
The package registry API relies on the manifest data to display package information like version, dependencies and scripts.
What is the expected correct behavior?
There should be no discrepancy between the manifest file and the contents of the package.json
inside the package itself.