How it will work: 3 steps
- 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.
- 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. - 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
skippedrow 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
osvIdsandaliases. - 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.
fixedInis the lowest version that fixes every merged advisory on the branch of your version. Fordjango 3.2.0it is a 3.2.x version, not an older 2.2.x fix.
Good for
- Check a project's
package-lock.jsonorrequirements.txtbefore 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_vulnerabilitiesrow. - 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.15is 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
- 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]andnpm:[email protected]. - Click Start.
- Open the Overview view in the Output tab. Check
severity,vulnerabilityIdandfixedIn. - Replace the list with your own packages, or paste a whole file into package.json, package-lock.json or requirements.txt.
Use cases
| Task | Input | Key fields |
|---|---|---|
| Check a Node.js project | packageLockJson | packageName, version, severity, fixedIn, dependencyType |
| Check a Python project | requirementsTxt | severity, cveIds, fixedIn, versionSource |
| Only urgent issues | any input + minSeverity: "HIGH" | rows with HIGH or CRITICAL only |
| Enrich an SBOM or inventory | dependencies list | cveIds, 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.jsonandrequirements.txtup 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
errorrows and the run isCAPPED. 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
| Symptom | Check | Action |
|---|---|---|
A package you know is vulnerable shows no_known_vulnerabilities | packageName, ecosystem, version | Check 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_VERSION | requestedVersionSpec | Give an exact version, or paste the lockfile instead of package.json. |
skipped with UNSUPPORTED_ECOSYSTEM | ecosystem | Use one of the 14 supported ecosystems. OS packages are not supported. |
error rows or PARTIAL | RUN_SUMMARY.message | OSV did not answer. Run again later. |
CAPPED | RUN_SUMMARY.message, counts.notCheckedOverLimit | Raise maxDependencies (up to 2,000) or your maximum cost per run, or split a very large input into two runs. |
Run failed with INVALID_INPUT | the run status message | Typical 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.
{
"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)
| Field | Type | Meaning |
|---|---|---|
resultType | string | vulnerable = 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. |
ecosystem | string | OSV ecosystem, e.g. npm, PyPI, Maven. |
packageName | string | Package name as sent to OSV, e.g. lodash, org.apache.logging.log4j:log4j-core. |
version | string | Version checked. Null when it could not be determined (skipped). |
requestedVersionSpec | string | Version text from your input, e.g. ^4.17.15 or >=2.19.1. |
versionSource | string | exact, range_minimum (lowest version of an npm range), lower_bound (requirements >= / ~=) or lockfile. |
inputSource | string | Where the dependency came from: dependencies, packageJson, packageLockJson or requirementsTxt. |
dependencyType | string | prod, dev, optional or peer (manifests only). |
vulnerabilityId | string | Main id of the vulnerability (GHSA preferred, then PYSEC/RUSTSEC/GO, then others, then CVE). |
osvIds | array | OSV records merged into this row because they describe the same issue. |
aliases | array | Other ids of the same issue (CVE, GHSA, PYSEC…), without duplicates. |
cveIds | array | CVE ids of the issue. |
ghsaIds | array | GitHub advisory ids of the issue. |
summary | string | One-line summary (max 500 characters). |
details | string | Advisory text (max 4000 characters). |
severity | string | CRITICAL, HIGH, MEDIUM, LOW or UNKNOWN. Null for non-vulnerable rows. |
severitySource | string | ghsa_database (GitHub reviewed label), cvss_v4, cvss_v3, cvss_v2 or ecosystem_specific. |
cvssScore | number | Highest CVSS base score in the group. |
cvssVector | string | CVSS vector for that score. |
cvssVersion | string | CVSS version, e.g. 3.1 or 4.0. |
cweIds | array | CWE weakness ids. |
fixedIn | string | Lowest version that fixes every merged advisory on the branch of your version. Null when no fix is published for that branch. |
fixedVersions | array | All fixed versions across branches. |
affectedRanges | array | Affected intervals for this package: {type, introduced, fixed, lastAffected}. |
published | string | Earliest publication time in the group (ISO 8601). |
modified | string | Latest modification time in the group (ISO 8601). |
withdrawnAliases | array | Aliases withdrawn by their database; they are listed for transparency and do not affect severity. |
references | array | Advisory, fix and report links: {type, url}, max 30. |
advisoryUrl | string | OSV.dev page of the vulnerability. |
databaseSource | string | Original advisory database link when OSV provides one. |
errorCode | string | For skipped/error rows: UNSUPPORTED_ECOSYSTEM, MISSING_VERSION, UNRESOLVABLE_VERSION, INVALID_DEPENDENCY, SOURCE_UNAVAILABLE, DEADLINE_REACHED… |
message | string | Human-readable explanation for below_severity_filter, clean, skipped and error rows. |
provider | string | Always OSV.dev. |
fetchedAt | string | When the row was produced (ISO 8601). |
Input settings (10)
The main fields of the input form. With the API you send them as JSON.
| Setting | Name in the API | Type | Example value |
|---|---|---|---|
| Dependencies (ecosystem:name@version) | dependencies | array | ["npm:[email protected]", "npm:[email protected]", "npm:[email protected]", "PyPI:[email protected].… |
| package.json | packageJson | string | |
| package-lock.json | packageLockJson | string | |
| requirements.txt | requirementsTxt | string | |
| Default ecosystem | defaultEcosystem | string | "npm" |
| Minimum severity | minSeverity | string | "LOW" |
| Include vulnerabilities without a severity | includeUnknownSeverity | boolean | true |
| Output clean dependencies | includeCleanDependencies | boolean | true |
| Include dev dependencies | includeDevDependencies | boolean | true |
| Max dependencies | maxDependencies | integer | 500 |
