Distinguish two vulnerabilities impacting the same dependency but with different versions

Summary

When Dependency Scanning finds the same vulnerabilities on two versions of the same package, we end up with the same CompareKey and location_fingerprint, so the two occurrences will be considered duplicates and deduped.

This is mainly an issue with NPM packages, other technologies often resolve dependencies to only one version per package.

The problem affects gemnasium and retire.js; they both rely on the DependencyScanningVulnerability.compareKey method to generate the compare key, and that method simply ignores the package version.

We could inject the package version in the compare key but then the vulnerability feedback would be invalidated whenever a dependency is upgraded, even if the new version is still affected by the same vulnerability. For instance, if a project depends on hawk v3.1.0 affected by CVE-2016-2515 and the vulnerability has been dismissed, it will come back and appear as new when the project upgrade to v3.1.1, which is also affected. Same goes for issues created from vulnerabilities.

Also, changing the way we forge the compare keys will result in loosing existing vulnerability feedback.

Steps to reproduce

Create a project with:

  • package.json: https://gitlab.com/gitlab-org/security-products/tests/js-npm/blob/1b502aaf3fc2cfdc67b5adbfeb874811ca3b738e/package.json
  • package-lock.json: https://gitlab.com/gitlab-org/security-products/tests/js-npm/blob/1b502aaf3fc2cfdc67b5adbfeb874811ca3b738e/package-lock.json

Run dependency scanning

Example Project

https://gitlab.com/gitlab-org/security-products/tests/js-npm

What is the current bug behavior?

Two vulnerabilities on different versions are reported as one vulnerability

What is the expected correct behavior?

Two vulnerabilities on different versions are reported as two separate vulnerabilities

Possible fixes

Track the ancestor(s) of the affected dependency in the scanners (gemnasium, retire.js), and inject them in the compare key. The change would be limited to npm. This is fairly complex. Also, gemnasium doesn't track the ancestor chain at the moment.

Alternatively, we could inject the package version in the compare key, resulting in the compare keys being more accurate (not merged) but less stable. Again, the change would be limited to npm.

Edited Sep 18, 2019 by Fabien Catteau
Assignee Loading
Time tracking Loading