I'm working on the app that is not yet publicly available and during the preparation for the launch, we made a full code scan to find any vulnerabilities.
We discovered that some of the dependencies used in our codebase depend on old and potentially harmful packages.ย
It was like we need packageA
but that library depends on the vulnerable library packageB
.
We needed to take proper action as soon as possible.
Yarn solution
What I've found was the fact that it's relatively easy to force some deeply nested dependencies in the yarn package manager:
Yarn supports selective version resolutions, which lets you define custom package versions or ranges inside your dependencies through the resolutions field in your package.json
file.
How to useย it?
We need to add resolutions
to our package.json
instructing Yarn how to handle dependencies:
{
"name": "project",
"version": "1.0.0",
"dependencies": {
"left-pad": "1.0.0",
"c": "file:../c-1",
"d2": "file:../d2-1"
},
"resolutions": {
"d2/left-pad": "1.1.1",
"c/**/left-pad": "^1.1.2"
}
}
That will install version 1.0.0 of left-pad
alongside locally stored c
and d2
. But it will install version 1.1.1 of left-pad
for d2
and version ^1.1.2 for any dependencies requiring left-pad
somewhere under c
.
NPM implementation
If you use npm instead of yarn, you can achieve a similar effect using the overrides setting in package.json
. There are some differences though.
We can't use glob matching (double asteriskโ-โ **
) instead, we have to nest dependencies:
{
"overrides": {
"foo": {
".": "1.0.0",
"bar": "1.0.0"
}
}
}
In that example, we're overriding foo
package to be at version 1.0.0 and making bar
at any depth beyond foo also 1.0.0.
Final words
With those, maybe, lesser-known options, we can force a newer (or simply other) version of any deeply nested package. This is a way for fixing issues when one of our dependency packages relies on e.g. not maintaining any more packages containing e.g. vulnerabilities.
Top comments (0)