Container CVE Matcher
Under maintenancePricing
from $1.00 / 1,000 dependency cve checkeds
Container CVE Matcher
Under maintenanceMatches a dependency list, lockfile, or SBOM against OSV.dev to report
Pricing
from $1.00 / 1,000 dependency cve checkeds
Rating
0.0
(0)
Developer
Dennis
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
Matches a dependency list, lockfile, or SBOM against OSV.dev to report exactly which CVEs/GHSAs apply to each installed version — not just "this package has had a CVE at some point", but a real answer to "does my exact version actually fall inside the affected range?", using the same range-comparison libraries npm and pip themselves use, plus CVSS severity and the patched version to upgrade to.
When should an AI agent use this?
- "Is this exact version of
lodashI have pinned actually vulnerable, or was that CVE fixed before this version?" - "Scan this package-lock.json/requirements.txt for known vulnerabilities before I merge this PR."
- "Given this CycloneDX/SPDX SBOM, which components have unpatched CVEs, and how severe are they?"
- "I know I have
flask==0.12andrequests==2.28.0installed — check both against known CVEs." - "Before recommending this npm package version to a user, confirm it isn't currently flagged for a critical vulnerability."
A composite semver range like >=2.0.0 <2.4.5 || >=3.0.0-alpha <3.0.1 — with pre-release ordering,
multiple disjoint intervals, and an ecosystem-specific version scheme (npm semver vs. Python's
PEP 440, which order versions differently) — is exactly the kind of exact, deterministic
computation a language model cannot reliably "eyeball" from training data. CVE data is also
inherently time-sensitive: new advisories publish daily, so even a very recently trained model
cannot know about a CVE published after its training cutoff. This Actor exists to give an agent a
verifiable, live answer instead of a guess.
What this Actor does
- Accepts a public git repository URL (shallow-cloned, no
gitbinary required), and/or one or more lockfiles/SBOMs pasted directly as text, and/or a direct flat package+version list — any combination, so an agent that already knows its own dependency graph can skip file parsing entirely - Parses npm
package-lock.json(both the legacy nested-tree format and the modern flat"packages"map) and PyPIrequirements.txt/Pipfile.lock, plus CycloneDX and SPDX SBOM JSON files (via each component'spurl) - Batch-queries OSV.dev's free, key-free API (
POST /v1/querybatch) for every dependency, then fetches full advisory details only for the vulnerabilities that actually came back — never one request per dependency per advisory - Re-verifies every match itself against the exact installed version, rather than trusting OSV's
batch response at face value: npm ranges are checked with the
semverpackage (the same library npm itself uses), PyPI ranges with@renovatebot/pep440(a maintained PEP 440 implementation used in production by Renovate) — correctly handling composite/disjoint ranges, open-ended "still unfixed" ranges, and inclusive-vs-exclusive upper bounds - Computes a real CVSS base score + severity level from OSV's CVSS vector string (using
ae-cvss-calculator, supporting CVSS v2/v3/v4), falling back to GHSA's own qualitative severity label when no CVSS vector is present - Reports the exact patched version to upgrade to, taken directly from the matching range's fix boundary
- Returns clean, flat JSON records: one run-summary record, one record per checked dependency (including unsupported-ecosystem and unresolved-version dependencies — never silently dropped), and one record per confirmed CVE/GHSA match
Supported ecosystems (v1)
| Ecosystem | Lockfile/manifest support | Exact-version range matching |
|---|---|---|
| npm | package-lock.json (v1/v2/v3), CycloneDX/SPDX pkg:npm/... | ✅ via the semver npm package |
| PyPI | requirements.txt (pinned == lines), Pipfile.lock, CycloneDX/SPDX pkg:pypi/... | ✅ via @renovatebot/pep440 |
OSV.dev itself covers many more ecosystems (Go, Maven, RubyGems, crates.io, Packagist, NuGet, ...),
and a CycloneDX/SPDX SBOM can freely describe components from any of them. This Actor never
drops a dependency it can't check — a component from an unsupported ecosystem is still reported
as a "dependency" record (with supported: false and a lookupError explaining why), it just
isn't queried against OSV. This is a deliberate, honest v1 scope limit rather than a half-correct
guess: getting exact version ordering right for Go's pseudo-versions, Maven's version-comparison
rules, RubyGems' segment rules, etc. each needs its own verified library, and only npm/PyPI have
one with the maturity this Actor requires (see PROJECTINFORMATIE.txt for the full reasoning).
A dependency with only a version range (e.g. an unpinned requirements.txt line or a
package.json-style caret range) is likewise reported but not checked — this Actor matches an
exact installed version, never a range against a range, to avoid a false sense of certainty.
Input
| Field | Type | Description | Example |
|---|---|---|---|
repoUrl | string | Public git repository to clone (https:///http:// only) | "https://github.com/expressjs/express.git" |
gitRef | string | Branch/tag/commit to check out (default: repo's default branch) | "main" |
manifests | array of {filename, content} | Lockfile/SBOM contents pasted directly | see below |
dependencies | array of {name, version, ecosystem} | A direct package+version list, ecosystem defaults to "npm" | see below |
maxDependencies | integer | Cap on dependencies checked in one run, 1-1000 (default 300) | 300 |
At least one of repoUrl, manifests, or dependencies is required (any combination is fine).
{"dependencies": [{ "name": "lodash", "version": "4.17.15", "ecosystem": "npm" },{ "name": "flask", "version": "0.12", "ecosystem": "PyPI" }]}
{"manifests": [{"filename": "requirements.txt","content": "flask==0.12\nrequests==2.31.0\n"}]}
Output
One "project" record per run:
{"recordType": "project","scanId": "b1e6...","input": "2 direct dependencies","totalDependenciesFound": 2,"totalDependenciesChecked": 2,"totalUnresolvedVersions": 0,"totalUnsupportedEcosystem": 0,"totalMatches": 1,"highestSeverity": "medium","ecosystemsSupported": ["npm", "PyPI"],"error": null}
One "dependency" record per reported dependency (checked or not):
{"recordType": "dependency","scanId": "b1e6...","name": "lodash","ecosystem": "npm","supported": true,"version": "4.17.15","versionRange": null,"checked": true,"matchCount": 1,"highestSeverity": "medium","lookupError": null}
One "match" record per confirmed CVE/GHSA finding:
{"recordType": "match","scanId": "b1e6...","name": "lodash","ecosystem": "npm","installedVersion": "4.17.15","vulnId": "GHSA-29mw-wpgm-hmr9","cveId": "CVE-2020-28500","aliases": ["CVE-2020-28500"],"summary": "Regular Expression Denial of Service (ReDoS) in lodash","severityLevel": "medium","cvssVector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L","cvssScore": 5.3,"affectedRange": ">=4.0.0 <4.17.21","fixedVersion": "4.17.21","url": "https://nvd.nist.gov/vuln/detail/CVE-2020-28500","published": "2022-01-06T20:30:46Z","modified": "2025-09-29T21:12:31.102523Z"}
severityLevel is one of critical, high, medium, low, none (a score of exactly 0), or
unknown (no CVSS vector and no GHSA qualitative label could be found — never guessed).
Using this Actor as an MCP tool for AI agents
Every public Apify Actor is automatically exposed as a callable "tool" via Apify's MCP server. This Actor is designed for that use case specifically:
- Flat, typed output — no nested objects; every field is a string/number/boolean/array of
strings, easy for an agent to filter on (
severityLevel === "critical") or aggregate - Three independent input modes — an agent that already knows
{name, version}pairs from its own dependency resolution doesn't need to construct a fake lockfile; it can passdependenciesdirectly and skip file parsing entirely - Never silently drops or guesses — an unsupported ecosystem, an unpinned version, or a failed
advisory-detail fetch is always reported as its own record with a
lookupErrorexplaining why, rather than being absent from the output or a false "0 matches" - Deterministic, source-cited output — every match carries the exact
affectedRangeandfixedVersionthat produced it, so an agent (or a human reviewing its work) can verify the claim against the linked advisoryurl - Bounded cost/runtime —
maxDependenciesand a per-request timeout on every OSV.dev call prevent a single run from becoming unexpectedly large or slow
Use cases
- Pre-merge CI-style check: does this dependency bump introduce a new, currently-unpatched CVE?
- Triage a legacy/inherited codebase: "what are we actually running, and is any of it flagged?"
- Verify a CycloneDX/SPDX SBOM (e.g. generated by a build pipeline) against live vulnerability data
- Spot-check a single package version before an agent recommends or installs it
How exact-version matching works (and its limits)
OSV.dev's batch API deliberately returns only candidate vulnerability IDs per package+version —
not a pre-verified "yes this exact version is affected" answer (see PROJECTINFORMATIE.txt for the
live-captured API shape). This Actor treats that as a candidate list only: it fetches each
candidate's full advisory record and re-walks its affected[].ranges[].events sequence itself,
using the ecosystem's real version-comparison library, before ever reporting a match. A range with
multiple introduced/fixed/last_affected pairs (e.g. a vulnerability re-introduced in a later
branch) is walked as the sequence of intervals it actually represents, not approximated as one
simple >=/< pair. OSV's optional explicit versions enumeration (when present) is checked too,
as additional confirmation alongside the range walk.
This is not a replacement for a full SCA platform (Snyk, Trivy, Grype, Dependabot) — it is a narrowly-scoped, verifiable single-purpose tool: given an exact version, tell me precisely which CVEs apply and why, callable ad-hoc without an account or CI integration. Always have a qualified professional review a genuine security-critical finding before acting on it.
Legal
This Actor only clones public repositories you provide a URL for, or reads lockfile/SBOM/ dependency text you supply directly — it never accesses private repositories or credentials, and never performs any exploit or intrusive testing against the packages it reports on. Vulnerability and version metadata is technical data about software packages, not personal data. Findings are informational, not a certification of security or a substitute for a full security audit.
FAQ
Q: Does this replace Snyk / Trivy / Grype / Dependabot? A: No. Those are full CI/CD-integrated SCA platforms. This Actor is a narrowly-scoped, ad-hoc tool — call it once, get a verified answer, no account or pipeline integration required. That makes it specifically well-suited to on-demand use by a coding agent.
Q: Why does OSV say a package is vulnerable but this Actor reports 0 matches for it? A: OSV's batch endpoint can return a candidate ID for a package name+version pair loosely, but this Actor always re-verifies the exact range before reporting a match. If your exact version turns out to be outside every affected interval (e.g. you're on a version released after the fix), it's correctly excluded — that's the whole point of doing real range matching instead of trusting the package name alone.
Q: What happens if a dependency's ecosystem isn't supported (e.g. Maven, Go, RubyGems)?
A: It's still reported as a "dependency" record with supported: false and an explanatory
lookupError — never silently dropped from the output.
Q: What happens to an unpinned dependency (e.g. requests>=2.0, no exact version)?
A: It's reported with version: null, checked: false, and a lookupError explaining that no
exact version was available — this Actor never checks a range against a range.
Q: Can this scan a private repository?
A: No — only https:///http:// public repository URLs are accepted (no authentication is
performed). For a private repo, paste its lockfile/SBOM/dependency list directly instead.
Q: Does the CVSS score come from this Actor's own calculation?
A: The vector string comes directly from OSV.dev; the numeric base score is computed from that
vector using ae-cvss-calculator, a maintained third-party CVSS implementation — not a
hand-rolled reimplementation of the CVSS formula.
Keywords
cve, vulnerability-scanner, osv, sbom, sca, dependency-audit, security, npm, pypi, cyclonedx, spdx, software-composition-analysis
Related Actors
- Legacy Code License Scanner — the license-compliance counterpart to this Actor: same git-clone/manifest-parsing approach, but checking license conflicts instead of CVEs. Complementary, not overlapping — run both for a full pre-dependency-add check (license risk + security risk).
Changelog
0.1.0
- Initial release: git-clone / inline-manifest-SBOM / direct-dependency-list scanning, OSV.dev batch querying, npm-semver and PEP 440 exact-version range re-verification, CVSS scoring.