Safeguard
AppSec

OSS Scan: How to Scan Open Source Dependencies for Vulnerabilities

An OSS scan finds known vulnerabilities in the open source packages your code depends on. Here is how the scan works, where it fits in CI, and how to act on results.

Safeguard Team
Product
6 min read

An OSS scan is the process of analyzing your project's open source dependencies against databases of known vulnerabilities to find which packages expose you to disclosed CVEs, and it is the single highest-leverage security check most teams can add, because open source makes up the large majority of a typical application's code. If you write software today, you assemble it far more than you author it, and an open source security scan is how you find out what you inherited.

This guide covers what an OSS scan looks at, how the underlying matching works, and how to turn a wall of findings into a short list of things worth fixing.

What an OSS scan actually inspects

The scan does not read your business logic. It reads your dependency manifests and lockfiles, builds the full transitive dependency graph, and compares every resolved package and version against vulnerability data. Depending on your stack, the inputs are files like:

  • package-lock.json or yarn.lock for Node
  • requirements.txt, poetry.lock, or Pipfile.lock for Python
  • pom.xml or build.gradle for Java
  • go.sum for Go
  • Cargo.lock for Rust

The lockfile matters more than the manifest, because it records the exact versions that were resolved, including transitive dependencies you never named. Most real exposure lives in those transitive packages, the dependencies of your dependencies, which is exactly where a manual review breaks down.

How the matching works

Under the hood an OSS scan produces a software bill of materials (SBOM), a complete inventory of components and versions, then matches each entry against advisory sources. The main sources are the National Vulnerability Database (NVD), the GitHub Advisory Database, and ecosystem-specific feeds like the Python Packaging Advisory Database or RustSec.

Matching sounds trivial and is not. The hard parts are version range interpretation (does advisory range >=2.0.0 <2.14.2 include the version you resolved?), package name normalization across ecosystems, and deduplication when the same flaw appears in multiple feeds with different identifiers. This is why two scanners can report different counts on the same project, and why false positives happen. A good scanner leans on structured data like the OSV schema and CPE or PURL identifiers to keep the matching precise.

Reachability: the difference between a count and a risk

A raw OSS scan of a large project routinely returns hundreds of findings. Most teams cannot fix hundreds of things, and most of those findings do not matter, because the vulnerable code path is never actually called from your application.

This is where reachability analysis changes the picture. Instead of reporting every advisory in every installed package, reachability-aware scanning asks whether your code can actually reach the vulnerable function. A critical CVE in a package you import but only use for an unrelated feature may be unreachable in practice. Prioritizing reachable findings turns an unmanageable backlog into a handful of genuinely urgent fixes. Tools such as Safeguard apply this kind of analysis to rank findings by whether they are actually exploitable in your context.

Reachability is not a reason to ignore unreachable findings forever, since a future code change can make them reachable, but it is the right way to sequence work.

Wiring an OSS scan into CI

An OSS scan delivers the most value when it runs automatically on every change, not as an occasional manual sweep. A minimal pipeline stage runs the scan, fails the build on new high-severity issues, and lets existing accepted risks pass. Conceptually:

# Generate an SBOM, then scan it
oss-scan --path . --fail-on high --ignore-file .oss-ignore.yaml

Two rules keep this from becoming a source of friction. First, gate on new findings introduced by the change, not the total historical count, so a legacy backlog does not block unrelated work. Second, keep an ignore or waiver file in version control with an expiry date on each entry, so accepted risks are documented and revisited rather than silently forgotten.

Run the scan in more than one place. A pre-commit or IDE-level check gives developers fast feedback, the CI gate enforces the policy, and a scheduled scan of your main branch catches newly disclosed vulnerabilities in dependencies you have not changed. That last one is important: a package you shipped six months ago can become vulnerable tomorrow when a new CVE is published against it, with no code change on your side.

Acting on results

When a finding lands, you have a small set of moves. Upgrade to a patched version, which is almost always the right first choice. If no patch exists, check whether a configuration change removes the exposure, or whether the vulnerable feature can be disabled. If the finding is unreachable or clearly a false positive, waive it with a documented reason and an expiry. Only as a last resort do you accept a live, reachable risk, and that decision should be explicit and owned.

For transitive findings where you do not control the version directly, dependency overrides let you force a patched release, the same mechanism covered in our dependency management guides. Track your mean time to remediate as a health metric, because the goal is not zero findings, it is a short and shrinking window between disclosure and fix.

FAQ

What is an OSS scan?

An OSS scan analyzes your project's open source dependencies, including transitive ones, against known-vulnerability databases like NVD and the GitHub Advisory Database to identify which packages expose you to disclosed CVEs. It is the core function of software composition analysis.

How is an open source security scan different from SAST?

SAST analyzes your own source code for flaws you wrote. An OSS scan analyzes the third-party packages you depend on for known, published vulnerabilities. They are complementary: one covers first-party code, the other covers the far larger body of code you inherited.

Why do two OSS scanners report different results?

Because vulnerability matching depends on how each tool interprets version ranges, normalizes package names, and deduplicates advisories across data sources. Differences in reachability analysis also change which findings each tool surfaces as high priority.

How often should an OSS scan run?

On every pull request for fast feedback, as a blocking CI gate before merge, and on a schedule against your main branch to catch newly disclosed vulnerabilities in dependencies you have not changed.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.