Dependencies

Vulnerable packages across forty ecosystems, direct and transitive, with the safe version to move to.

Available Shipped. Everything on this page works in the current release.

Software composition analysis: which packages your project uses, and which of them have known vulnerabilities.

Where the finding lands

On the line that declares the dependency, in the file you would edit to change it. Not at the top of the file, and not on a lockfile entry you never wrote.

That sounds obvious and is the hardest part of the feature. Package parsers produce a list of names and versions with no position information at all, so the extension re-reads each manifest with a position-aware parser: byte offsets for JSON, node positions for YAML, the module syntax tree for go.mod, line matching for requirements.txt and Gemfile.

Where a format genuinely cannot give an exact position, the finding is anchored as closely as possible and marked as approximate rather than silently pretending to precision.

Transitive dependencies have no line to point at, because you never declared them. Those anchor in the lockfile, and carry the chain that introduced them:

introduced via express@4.17.1 → qs@6.5.2

Ecosystems

npm, PyPI, Go, Maven and Gradle, Cargo, RubyGems, NuGet, Composer, Swift, Hex, Pub, Conda, CocoaPods, Conan, vcpkg, CRAN, Hackage, opam, Nix, Zig, Julia, Crystal, Deno, Erlang, and more, along with Docker images, Helm charts, CI pipeline definitions and shell scripts that install packages.

Both declared manifests and installed trees are read, so a dependency present in node_modules but missing from package.json is still found.

What a finding tells you

  • Every advisory affecting the version in use, with CVSS, EPSS and SSVC
  • Whether it is in CISA’s or the EU’s Known Exploited Vulnerabilities catalogue
  • Whether public exploit code exists, and how mature it is
  • The safe version to move to, and whether that is a major bump
  • Whether the package is end-of-life or has been flagged as malicious
  • Where it came from, if you did not add it yourself

Tuning

SettingDefaultEffect
vulnetix.sca.enabledtrueCheck dependencies at all
vulnetix.sca.safeHarbourStrategysafestWhich replacement version a quick fix moves to: safest, stable or latest
vulnetix.sca.maxMajorBump0How many major versions a suggested fix may cross
vulnetix.sca.annotateLockfilestrueWhether lockfiles get findings of their own
vulnetix.diagnostics.minimumSeveritylowHide findings below a threshold
vulnetix.diagnostics.showSuppressedfalseShow suppressed findings as hints instead of hiding them

The strategy default differs from the CLI on purpose. vulnetix fix defaults to stable; the editor defaults to safest, because a one-click fix behind a lightbulb gets less deliberation than a command someone typed, so it should prefer the smallest change that resolves the finding.

Network use

Matching a package to advisories requires the vulnerability database; there is no local copy. Only package coordinates are sent, never code. Results are cached, and a manifest save whose dependency set did not change produces no request at all. See privacy.

When each thing happens

Two passes, because the two questions cost different amounts.

Declared dependencies are checked in bulk when the workspace opens, and again when a manifest or lockfile changes. That pass answers the only thing the whole workspace needs to know: is anything wrong here.

Ranked replacement versions are resolved separately, for the manifest you have open. They are per-package work on the server and only useful for a file someone is looking at. So a package that came back clean shows a quiet checked marker straight away, while a vulnerable one shows a pending marker until its replacement versions arrive.

Ranked Safe-Harbour versions are a Pro feature. On the community tier the hover says so, rather than reporting that no fix exists — a different and much more discouraging claim.

Suppressing a finding

Rules in the repository’s .vulnetix/memory.yaml apply in the editor exactly as they do in CI. Point vulnetix.memory.path elsewhere if that file lives somewhere else.

vulnetix.suppressions adds editor-level rules on top, which take precedence. Use them to silence a finding for yourself without committing a change the whole team shares:

"vulnetix.suppressions": [
  { "findingId": "CVE-2021-23337", "reason": "not reachable from our entry points" },
  { "ruleId": "VNX-JS-001", "path": "test/fixtures", "reason": "intentional" }
]

A rule anchored on nothing is refused, because it would silence everything.

Didn't find what you needed? Tell us what's missing · Ask a question · Edit this page