Question

yarn upgrade to fix yarn audit errors

So, as of now, it appears that there is no yarn audit --fix, so I am trying to figure out how to go about fixing my yarn audit errors.

I have tried a yarn upgrade which has fixed some of the errors (which is great), but there are still several remaining.

I then tried a yarn add <package>@latest for the remaining high vulnerabilities, but it upgrades the version in my package.json, when I think the issue is coming from a dependency of a package that I am using.

Here is an example of some of my remaining errors:

┌───────────────┬──────────────────────────────────────────────────────────────┐
│ high          │ Regular Expression Denial of Service                         │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package       │ minimatch                                                    │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Patched in    │ >=3.0.2                                                      │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ gulp                                                         │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path          │ gulp > vinyl-fs > glob-stream > glob > minimatch             │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info     │ https://nodesecurity.io/advisories/118                       │
└───────────────┴──────────────────────────────────────────────────────────────┘
┌───────────────┬──────────────────────────────────────────────────────────────┐
│ high          │ Regular Expression Denial of Service                         │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package       │ minimatch                                                    │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Patched in    │ >=3.0.2                                                      │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ gulp                                                         │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path          │ gulp > vinyl-fs > glob-stream > minimatch                    │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info     │ https://nodesecurity.io/advisories/118                       │
└───────────────┴──────────────────────────────────────────────────────────────┘
┌───────────────┬──────────────────────────────────────────────────────────────┐
│ high          │ Regular Expression Denial of Service                         │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package       │ minimatch                                                    │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Patched in    │ >=3.0.2                                                      │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ gulp                                                         │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path          │ gulp > vinyl-fs > glob-watcher > gaze > globule > glob >     │
│               │ minimatch                                                    │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info     │ https://nodesecurity.io/advisories/118                       │
└───────────────┴──────────────────────────────────────────────────────────────┘
┌───────────────┬──────────────────────────────────────────────────────────────┐
│ high          │ Regular Expression Denial of Service                         │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package       │ minimatch                                                    │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Patched in    │ >=3.0.2                                                      │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ gulp                                                         │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path          │ gulp > vinyl-fs > glob-watcher > gaze > globule > minimatch  │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info     │ https://nodesecurity.io/advisories/118                       │
└───────────────┴──────────────────────────────────────────────────────────────┘
┌───────────────┬──────────────────────────────────────────────────────────────┐
│ moderate      │ Prototype Pollution                                          │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package       │ lodash                                                       │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Patched in    │ >=4.17.11                                                    │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ gulp                                                         │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path          │ gulp > vinyl-fs > glob-watcher > gaze > globule > lodash     │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info     │ https://nodesecurity.io/advisories/782                       │
└───────────────┴──────────────────────────────────────────────────────────────┘
 46  22491  46
1 Jan 1970

Solution

 45

The solution to this problem in yarn is called selective version resolutions which is basically defining resolutions for the transitive dependencies in the package.json.

The transitive dependencies are the dependencies of dependencies.

{
   "resolutions": { "**/**/lodash": "^4.17.12" }
}

So here even if the lodash isn't a direct dependency of your package, the dependent package in your package uses the version defined in the resolutions. Specific resolutions can also be provided. More info here.

2019-07-16

Solution

 18

While resolutions work, it is not the optimal solution, because:

  • you clutter your package.json with resolutions of transitive dependencies
  • you override the actually required version with what you think will work version. Assume A depends on B@^4.0.0 and you update B and resolve it to ^4.3.2. Some time later A gets an update and requires B@^5.0.0, but you still resolve B to ^4.3.2, which is not compatible anymore.

Here is another way to update transitive dependencies:

  1. delete the version of the dependency you want to update from yarn.lock
  2. run yarn install

This way you force yarn to resolve the dependency again and in most cases yarn will install a newer version of what you deleted from yarn.lock.

Example: let's assume that you want to update vulnerable minimist@0.0.8, then you need to delete an entry like this from your yarn.lock:

minimist@0.0.8:
  version "0.0.8"
  resolved "http://10.0.0.1/repository/npm-registry/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
  integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=

and then run yarn install.

If this doesn't help:

Try updating dependencies that are higher in the dependency chain:

  1. Run yarn why <dependency> to find out which packages pull it
  2. Go up the chain and try deleting the upper dependency in the chain from yarn.lock and then running yarn install

Example:

Here is an example, where we update a transitive dependency minimist:

$ yarn why minimist
.....
=> Found "mkdirp#minimist@0.0.8"
info This module exists because "eslint#mkdirp" depends on it.
=> Found "optimist#minimist@0.0.10"
info This module exists because "jest#jest-cli#@jest#core#@jest#reporters#istanbul-reports#handlebars#optimist" depends on it.
.....
  1. Delete minimist entries from yarn.lock and run yarn install -> this doesn't help, presumably because mkdirp and optimist require exactly minimist@0.0.8 and minimist@0.0.10
  2. Delete "direct parents" of minimist from yarn.lock: mkdirp and optimist.
  3. Run yarn install.
  4. Run yarn why minimist again:

    $ yarn why minimist
    .....
    => Found "mkdirp#minimist@1.2.5"
    info This module exists because "eslint#mkdirp" depends on it.
    => Found "optimist#minimist@0.0.10"
    info This module exists because "jest#jest-cli#@jest#core#@jest#reporters#istanbul-reports#handlebars#optimist" depends on it.
    .....
    

    Here we see that minimist@0.0.8 was updated to minimist@1.2.5, but minimist@0.0.10 still exists.

  5. Delete the next dependency in the dependency chain from yarn.lock: handlebars

  6. Run yarn install
  7. Run yarn why minimist - nothing changed, minimist@0.0.10 is still there.
  8. Delete the next dependency in the chain from yarn.lock: istanbul-reports
  9. Run yarn install
  10. Run yarn why minimist: minimist@0.0.10 is not there anymore, because istanbul-reports was updated.
2020-03-24