So you have a node.js project in which npm audit
tells you there is a dependency of a dependency
that needs to be updated, but doing a simple npm audit fix
won't do the
trick, and for some reason, you cannot just bump the first-level package
version and npm install
to update it, because the second-level dependency
package has no new version, so it won't try to resolve the new version of the
third-level (dependency) package.
Sounds familiar?
Well, it seems familiar to me at least, because this week, I had to make sure our dependencies have no vulnerabilities, and I had this exact problem:
package-1@^0.3.0
depends on:
package-2@^3.0.1 (which is not vulnerable in itself, but has no new version available)
depends on:
package-3@^4.3.2 (which is vulnerable, so it needs to be updated)
So I couldn't just bump the package-1 version in the package.json then npm
install
or yarn install
for it and also package-3 to be updated to safer
versions. Because since package-2 had no new version, it wouldn't even bother
to try and update its own dependencies.
That's when shrinkwrap
comes to the rescue
The npm shrinkwrap
command will create a npm-shrinkwrap.json
file alongside
your package.json
, where you can specify package-3
's desired version by
doing so:
{
"dependencies": {
"package-1": {
"version": "0.3.0",
"from": "package-1@^0.3.0",
"dependencies": {
"package-2": {
"version": "3.0.1",
"from": "package-2@^3.0.1",
"dependencies": {
"package-3": {
"version": "4.4.0",
"from": "package-3@^4.4.0"
}
}
}
}
}
}
}
See that 4.4.0? That's the version that fixes the vulnerability.
Yarn also has that kind of trick, but it's cleaner (IMHO)
Yarn also has a feature that
lets you specify the version that you want for our hypothetical package-3
example package.
Simply put, all you have to do is to add a "resolutions" object property inside your package.json, and set the version like so:
{
...
"resolutions": {
"package-1/**/package-3": "^4.4.0"
}
}
... where 4.4.0 and later minor versions are fixing the vulnerability you want to squish.