OSV.dev logo

Developer tools · Coming soon

Dependency Vulnerability Scanner with OSV Data

Paste a package list, package.json, package-lock.json or requirements.txt. You get one row per known vulnerability with severity and CVSS. It also shows the fix version for your branch.

Built and tested. Prices will be shown after release.

Coming soon to the Apify StoreFollow us on Apify

What you get, for example

resultTypevulnerable
ecosystemnpm
packageNameminimist

How it will work: 3 steps

  1. Follow us on ApifyThe tool is built and waits in the queue for the Apify Store. Apify is the cloud platform where our tools run.
  2. Paste your input and press StartNo code needed: you fill in a form (the input). It already has a working example. For example: npm:[email protected] in Dependencies (ecosystem:name@version). Each start is one run.
  3. Download the resultsWhen the run ends, the results are in a table (the dataset). Open Output, press Export and pick Excel or CSV. JSON and the API are there too.

This tool is an Apify Actor: a small program that runs on Apify. You can also run it on a schedule, for example every Monday. New to it? Read how it works, step by step and the 8 words you need first.

What it does

Dependency Vulnerability Scanner checks your npm, PyPI, Maven, Go, Cargo and other packages for known vulnerabilities in the free OSV.dev database. Paste a list such as npm:[email protected], a package.json, a package-lock.json or a requirements.txt. You get one row per vulnerability with the CVE and GHSA ids, severity, CVSS score, CWE and the version that fixes it on your version branch.

  • Reads your input. A list, a manifest or a lockfile. Duplicates are checked once. A line it cannot check (no version, a git URL, an unsupported ecosystem) gets a skipped row with the reason.
  • Finds known vulnerabilities for that exact version in OSV.
  • Merges duplicates. One issue often has several ids (for example GHSA, PYSEC and CVE). They become one row, and all ids are kept in osvIds and aliases.
  • Picks the severity. The GitHub reviewed label comes first, then the highest CVSS score (v4, v3 or v2), then the ecosystem's own rating. With no score at all the row says UNKNOWN. When aliases are merged into one row, the highest level among them counts; on a tie the GitHub label wins.
  • Finds the fix for your branch. fixedIn is the lowest version that fixes every merged advisory on the branch of your version. For django 3.2.0 it is a 3.2.x version, not an older 2.2.x fix.

Good for

  • Check a project's package-lock.json or requirements.txt before a release.
  • Get a list of packages to upgrade, with the target version for each.
  • Add CVE, CVSS and CWE data to an SBOM or a dependency inventory.
  • Run the same check on a schedule and export the rows to a spreadsheet or a ticket system.

Not a good fit

  • Proof that a package is safe. An empty result means OSV has no known advisory for that exact version. It does not prove the package is safe.
  • Typos and unknown packages. OSV answers the same way for an unknown name and for a clean package, so both get a no_known_vulnerabilities row.
  • Your code. The Actor checks package versions only. It does not scan source code, containers or OS packages (Debian, Alpine and similar are not supported).
  • Version ranges. A range like ^4.17.15 is checked at its lowest version. For the versions you really install, paste the lockfile.

Who uses it

Developers

Check a project's lockfile before a release.

Security teams

Get a list of packages to upgrade, with the target version.

Compliance teams

Add CVE, CVSS and CWE data to an SBOM or inventory.

Price

Prices will be shown after release.

Questions

Does an empty result mean I am safe?

No. It means OSV has no known issue for that version. It is not a proof of safety.

Why do I see fewer rows than other scanners?

Duplicate ids for the same issue are merged into one row.

Does it catch typos in package names?

No. OSV answers the same for an unknown name and a clean package.

How many packages can I check?

Up to 2,000 unique packages per run.

Why is the severity MEDIUM when the CVSS score is high?

GitHub has reviewed the advisory and set that label. The reviewed label comes first; cvssScore still shows the raw score.

How fresh is the data?

Each run asks OSV live. Each row has modified (last change of the advisory) and fetchedAt (our read time).

Details

Step by step on Apify
  1. Open the Input tab. The form already has six packages: npm:[email protected], npm:[email protected], npm:[email protected], PyPI:[email protected], PyPI:[email protected] and npm:[email protected].
  2. Click Start.
  3. Open the Overview view in the Output tab. Check severity, vulnerabilityId and fixedIn.
  4. Replace the list with your own packages, or paste a whole file into package.json, package-lock.json or requirements.txt.
Use cases
TaskInputKey fields
Check a Node.js projectpackageLockJsonpackageName, version, severity, fixedIn, dependencyType
Check a Python projectrequirementsTxtseverity, cveIds, fixedIn, versionSource
Only urgent issuesany input + minSeverity: "HIGH"rows with HIGH or CRITICAL only
Enrich an SBOM or inventorydependencies listcveIds, ghsaIds, cvssScore, cweIds, advisoryUrl
Tips for better results
  • Use a lockfile, not only package.json. Exact versions give better results.
  • Keep only HIGH and CRITICAL rows when you need a short urgent list.
  • Check skipped rows. They show lines without a version or with an unknown ecosystem.
Limits and good to know
  • Up to 2,000 unique packages per run (maxDependencies, default 500). A lockfile can be up to 8 MB; package.json and requirements.txt up to 1 MB each
  • A full run of 2,000 vulnerable packages took about 5.5 minutes in our test. The internal time budget is 10 minutes. Packages not reached in time get error rows and the run is CAPPED. Keep the run timeout at 900 seconds or more for large inputs
  • Only exact versions are checked. Ranges are checked at their lowest version, and lines without a version are skipped
  • The data is only as complete as OSV. A new advisory can take time to appear, and some advisories have no score or no fix yet

Troubleshooting

SymptomCheckAction
A package you know is vulnerable shows no_known_vulnerabilitiespackageName, ecosystem, versionCheck the spelling and the ecosystem. OSV treats an unknown name like a clean one. Some advisories are filed under another package name (for example Rails issues under actionpack).
skipped with MISSING_VERSION or UNRESOLVABLE_VERSIONrequestedVersionSpecGive an exact version, or paste the lockfile instead of package.json.
skipped with UNSUPPORTED_ECOSYSTEMecosystemUse one of the 14 supported ecosystems. OS packages are not supported.
error rows or PARTIALRUN_SUMMARY.messageOSV did not answer. Run again later.
CAPPEDRUN_SUMMARY.message, counts.notCheckedOverLimitRaise maxDependencies (up to 2,000) or your maximum cost per run, or split a very large input into two runs.
Run failed with INVALID_INPUTthe run status messageTypical causes: empty input, a file that is not valid JSON, a file over the size limit.

For developers

Sample result

One result from a real test run, in JSON. Real values change from run to run. In Excel or CSV each field is a column.

one result · JSON
{
  "resultType": "vulnerable",
  "ecosystem": "npm",
  "packageName": "minimist",
  "version": "1.2.0",
  "requestedVersionSpec": "1.2.0",
  "versionSource": "exact",
  "inputSource": "dependencies",
  "vulnerabilityId": "GHSA-xvch-5gv4-984h",
  "osvIds": ["GHSA-xvch-5gv4-984h"],
  "aliases": ["CVE-2021-44906"],
  "cveIds": ["CVE-2021-44906"],
  "ghsaIds": ["GHSA-xvch-5gv4-984h"],
  "summary": "Prototype Pollution in minimist",
  "severity": "CRITICAL",
  "severitySource": "ghsa_database",
  "cvssScore": 9.8,
  "cweIds": ["CWE-1321"],
  "fixedIn": "1.2.6",
  "advisoryUrl": "https://osv.dev/vulnerability/GHSA-xvch-5gv4-984h",
  "provider": "OSV.dev"
}
Data fields (34)
FieldTypeMeaning
resultTypestringvulnerable = one known vulnerability of this dependency; below_severity_filter = OSV lists vulnerabilities for this version but all are below your minimum severity; no_known_vulnerabilities = OSV has no matching advisory (not a guarantee of safety); skipped = not checked (unsupported ecosystem, missing or unresolvable version); error = OSV could not be reached for this dependency.
ecosystemstringOSV ecosystem, e.g. npm, PyPI, Maven.
packageNamestringPackage name as sent to OSV, e.g. lodash, org.apache.logging.log4j:log4j-core.
versionstringVersion checked. Null when it could not be determined (skipped).
requestedVersionSpecstringVersion text from your input, e.g. ^4.17.15 or >=2.19.1.
versionSourcestringexact, range_minimum (lowest version of an npm range), lower_bound (requirements >= / ~=) or lockfile.
inputSourcestringWhere the dependency came from: dependencies, packageJson, packageLockJson or requirementsTxt.
dependencyTypestringprod, dev, optional or peer (manifests only).
vulnerabilityIdstringMain id of the vulnerability (GHSA preferred, then PYSEC/RUSTSEC/GO, then others, then CVE).
osvIdsarrayOSV records merged into this row because they describe the same issue.
aliasesarrayOther ids of the same issue (CVE, GHSA, PYSEC…), without duplicates.
cveIdsarrayCVE ids of the issue.
ghsaIdsarrayGitHub advisory ids of the issue.
summarystringOne-line summary (max 500 characters).
detailsstringAdvisory text (max 4000 characters).
severitystringCRITICAL, HIGH, MEDIUM, LOW or UNKNOWN. Null for non-vulnerable rows.
severitySourcestringghsa_database (GitHub reviewed label), cvss_v4, cvss_v3, cvss_v2 or ecosystem_specific.
cvssScorenumberHighest CVSS base score in the group.
cvssVectorstringCVSS vector for that score.
cvssVersionstringCVSS version, e.g. 3.1 or 4.0.
cweIdsarrayCWE weakness ids.
fixedInstringLowest version that fixes every merged advisory on the branch of your version. Null when no fix is published for that branch.
fixedVersionsarrayAll fixed versions across branches.
affectedRangesarrayAffected intervals for this package: {type, introduced, fixed, lastAffected}.
publishedstringEarliest publication time in the group (ISO 8601).
modifiedstringLatest modification time in the group (ISO 8601).
withdrawnAliasesarrayAliases withdrawn by their database; they are listed for transparency and do not affect severity.
referencesarrayAdvisory, fix and report links: {type, url}, max 30.
advisoryUrlstringOSV.dev page of the vulnerability.
databaseSourcestringOriginal advisory database link when OSV provides one.
errorCodestringFor skipped/error rows: UNSUPPORTED_ECOSYSTEM, MISSING_VERSION, UNRESOLVABLE_VERSION, INVALID_DEPENDENCY, SOURCE_UNAVAILABLE, DEADLINE_REACHED…
messagestringHuman-readable explanation for below_severity_filter, clean, skipped and error rows.
providerstringAlways OSV.dev.
fetchedAtstringWhen the row was produced (ISO 8601).
Input settings (10)

The main fields of the input form. With the API you send them as JSON.

SettingName in the APITypeExample value
Dependencies (ecosystem:name@version)dependenciesarray["npm:[email protected]", "npm:[email protected]", "npm:[email protected]", "PyPI:[email protected].…
package.jsonpackageJsonstring
package-lock.jsonpackageLockJsonstring
requirements.txtrequirementsTxtstring
Default ecosystemdefaultEcosystemstring"npm"
Minimum severityminSeveritystring"LOW"
Include vulnerabilities without a severityincludeUnknownSeveritybooleantrue
Output clean dependenciesincludeCleanDependenciesbooleantrue
Include dev dependenciesincludeDevDependenciesbooleantrue
Max dependenciesmaxDependenciesinteger500

Start on Apify

Make a free Apify account: you get $5 of free usage every month. Missing a tool? Suggest it. We read every idea, but we do not promise to build it.

Apify links on this page are affiliate links. We may earn a commission. You pay the same price. Affiliate disclosure