osv-scanner: JVM dependency checks explained

osv-scanner matches dependency manifests against the open OSV vulnerability database; DevFlow uses it for Maven and Gradle projects, passing every pom.xml and Gradle lockfile in 1 call.

What the tool is

osv-scanner is an open-source command-line tool from Google that matches dependencies against OSV, an open database that gathers advisories from many ecosystems in one schema. It reads lockfiles and manifests of many package managers and reports the advisories that affect the resolved versions.

Which files DevFlow passes

DevFlow's JVM scanner walks the repository tree for pom.xml, gradle.lockfile and buildscript-gradle.lockfile, skipping .git, target, build and other output folders. Every match goes into one call of scan source with JSON output and one --lockfile flag per path.

A Gradle build without dependency locking has no gradle.lockfile, so osv-scanner covers Maven projects and Gradle projects that commit a lockfile. Turning on dependency locking is therefore the way to bring such a build into scope.

Severity in two steps

An OSV entry can carry a qualitative label in database_specific.severity. DevFlow uses that label first, mapping critical, high, moderate or medium, and low to its shared buckets.

When no label is present, DevFlow falls back to max_severity, a numeric CVSS score that osv-scanner reports per group of related advisories. It buckets that score with the standard ranges: under 4.0 low, under 7.0 moderate, under 9.0 high, and 9.0 or more critical.

Groups exist because one flaw is often published under several ids, for example a GHSA id and a CVE. Every id in a group gets that group's highest score, so aliases of the same flaw land in the same bucket.

What each finding records

  • the OSV id of the advisory;
  • the package name, kept once per package and id;
  • the advisory summary as the title;
  • the first fixed version in the affected ranges;
  • the link of a reference marked as an advisory, or else the osv.dev page for the id.

Exit codes and limits

osv-scanner exits with status 1 when it finds vulnerabilities, which DevFlow treats as normal as long as JSON came back. The call is bounded by the per-scan limit that DevFlow applies to each scanner, 300 seconds by default.

A worked example

Suppose a multi-module Maven project has a pom.xml at the root and one in each of three modules. DevFlow passes all four files in one call, and a library used by every module with one advisory is reported once.

Where results go

Findings are listed by name in the task's scan report, and the merge evidence section of the pull request counts them by severity for each repository. The recurring vulnerability poll runs the same scan on each default branch, every 12 hours by default, and each finding becomes an attention item.

FAQ

Why does DevFlow use osv-scanner only for Java projects?

DevFlow limits osv-scanner to JVM manifests so it does not report a second time what its dedicated Go, Node, .NET, Python and Rust scanners already find.

Why does DevFlow not use OWASP Dependency-Check for Java?

The DevFlow code notes that Dependency-Check is a heavy JVM application that downloads the NVD, while osv-scanner is a single static binary.