AI Agent Stack Dependency Vulnerability Scanner avatar

AI Agent Stack Dependency Vulnerability Scanner

Pricing

from $50.00 / 1,000 manifest scanneds

Go to Apify Store
AI Agent Stack Dependency Vulnerability Scanner

AI Agent Stack Dependency Vulnerability Scanner

Resolve packages from a supplied dependency manifest, query the public OSV.dev advisory database, and return a ranked, import-checked fix list plus one pass/fail gate.

Pricing

from $50.00 / 1,000 manifest scanneds

Rating

0.0

(0)

Developer

kingii98

kingii98

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a day ago

Last modified

Categories

Share

Give this Actor one or more dependency manifests as plain text. The Actor reads the packages named in each manifest, queries the public OSV.dev advisory database, and reports each vulnerable package with a CVSS score, a fix version, and an import-presence flag. It also writes one run-level pass/fail gate. The Actor answers one question: does this manifest pull in a known vulnerable package, and does the supplied source code import it?

The Actor does not clone a repository, install a package, or run any code from a manifest. It reads the text you supply and calls the public OSV.dev API only.

Supported ecosystems

EcosystemManifest text readHeuristic notes
PyPIrequirements.txt-style lines (name==version)Only exact == pins resolve; ranges and unpinned lines are skipped.
npmpackage.json, or an npm package-lock.json (v1 or v2/v3)A lock file's node_modules/ nesting marks transitive packages. A plain package.json strips a ^/~/range prefix to get a best-effort version and marks every entry DIRECT.
Gogo.modA // indirect comment marks a requirement TRANSITIVE.
Mavenpom.xml <dependency> blocksRead with a bounded regex extraction, not an XML parser, so a manifest cannot trigger XML entity expansion. A version that is still a ${property} placeholder cannot be resolved and is skipped. Every entry is marked DIRECT: a plain pom.xml does not show the resolved dependency tree.
crates.ioCargo.toml [dependencies] tables, or a Cargo.lockEvery entry is marked DIRECT: a version 1 scanner does not walk Cargo.lock's own dependency graph.

This is a heuristic manifest reader, not a package manager's dependency solver. It does not compute a lock file from a bare manifest, and it does not run call-graph analysis. The importPresence field is a plain text search for the package name in the source files you supply — a name match, not proof that the vulnerable code path is reachable.

Input

{
"manifests": [
{"name": "requirements.txt", "ecosystem": "PyPI", "content": "django==1.11.1\nsix==1.16.0\n"}
],
"sourceFiles": [
{"path": "app/settings.py", "content": "import django\n"}
],
"minCvss": 0.0,
"includeTransitive": true,
"failOnCvssAtOrAbove": 9.0
}
FieldDescription
manifests1-20 manifests. Each has name, ecosystem (PyPI, npm, Go, Maven, or crates.io), and content (the manifest text). Required.
sourceFilesOptional, up to 2000 files. Each has path and content. Used only for the importPresence text search.
minCvssDrop advisories below this CVSS score from the report and the gate. Default 0.0.
includeTransitiveResolve transitive packages when the manifest text carries that information. Default true.
failOnCvssAtOrAboveThe gate fails when any reported advisory's CVSS score is at or above this value. Default 9.0.

A run resolving more than 5000 packages across all manifests fails before any OSV.dev call is made.

Output

Every run writes one package-result record for each resolved package that has at least one advisory at or above minCvss, plus one gate-result record, to the default dataset.

Package result:

{
"recordType": "package-result",
"manifestName": "requirements.txt",
"ecosystem": "PyPI",
"packageName": "django",
"resolvedVersion": "1.11.1",
"dependencyKind": "DIRECT",
"vulnerabilities": [
{
"osvId": "GHSA-xxxx",
"aliases": ["CVE-2021-1234"],
"summary": "SQL injection in QuerySet",
"cvssScore": 9.8,
"cvssVector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"severityBand": "CRITICAL",
"introducedVersion": "0",
"fixedVersion": "1.11.5",
"publishedAt": "2021-01-01T00:00:00Z"
}
],
"importPresence": {"searched": true, "matchedFiles": ["app/settings.py"], "verdict": "IMPORTED"},
"upgradePath": {"currentVersion": "1.11.1", "lowestSafeVersion": "1.11.5", "isMajorBump": false}
}

importPresence.verdict is IMPORTED, NOT_IMPORTED, or UNKNOWN (no sourceFiles were supplied, so nothing was searched).

Gate result:

{
"recordType": "gate-result",
"gate": {"verdict": "FAIL", "highestCvss": 9.8, "failingPackageCount": 1, "threshold": 9.0},
"summary": {
"severityCounts": {"CRITICAL": 1, "HIGH": 0, "MEDIUM": 0, "LOW": 0, "NONE": 0, "UNKNOWN": 0},
"rankedFixList": [
{
"manifestName": "requirements.txt",
"packageName": "django",
"resolvedVersion": "1.11.1",
"highestCvss": 9.8,
"imported": "IMPORTED",
"lowestSafeVersion": "1.11.5"
}
]
}
}

rankedFixList is ordered by highestCvss descending, then by IMPORTED packages first. When gate.verdict is FAIL, the Actor run itself finishes with a non-zero exit code and a failed status message, so a CI job can gate a merge on the run outcome alone.

CVSS scoring

OSV.dev advisory records carry a CVSS v3 vector string, not a precomputed score. The Actor computes the CVSS v3.1 base score from that vector using the published formula. When an advisory has no CVSS v3 vector, cvssScore is null and severityBand falls back to the advisory's own qualitative severity label (or UNKNOWN when neither is present). A minCvss above 0.0 drops an unscored advisory rather than guessing whether it clears the floor.

Pricing

The Actor uses Apify pay-per-event pricing with three charge events:

EventChargedPrice
manifest-scannedOnce for each manifest in the input, parsed, resolved, and queried, whether or not it resolves to any package.$0.05
package-resolvedOnce for each package resolution. The same package repeated across manifests is charged once per manifest it appears in, because parsing it cost CPU again each time.$0.0006
vulnerability-detailedOnce for each distinct OSV.dev advisory actually retrieved and enriched. A package/version pair repeated across manifests reuses the same OSV.dev query and detail fetch, so the advisory is charged once, not once per manifest.$0.004

Apify platform usage (compute units and other resources consumed by the run) may still be shown to users according to their plan and Apify's pricing rules, as described in the Actor's listing.

Final pricing is configured in the Apify Store listing and may change subject to Apify's pricing-change notice rules.

Security and privacy

  • The Actor never fetches a URL you supply. It reads the manifest and source file text you pass in input, and it calls only the fixed, public OSV.dev API.
  • The Actor does not use a browser, proxy, LLM, external database, or paid API.
  • The Maven manifest reader is a bounded regex extraction, not an XML parser, so a pom.xml cannot trigger XML entity expansion.
  • Manifest count, resolved package count, source file count, and per-field text length are all bounded before parsing begins.

Do not place secrets, private tokens, or personal data in any input field.

Limitations

  • Version resolution is heuristic: only exact pins resolve for PyPI; npm, Maven, and crates.io manifests without a lock file report the versions stated in the manifest text, not a real dependency solver's result.
  • dependencyKind (DIRECT/TRANSITIVE) is only inferred where the manifest text itself carries that structure (an npm lock file's nesting, or a go.mod // indirect marker). Every other ecosystem reports DIRECT for every entry.
  • importPresence is a plain-text name search across the supplied source files. It is a signal, not proof of reachability: it can both miss a dynamic import and match an unrelated identifier that happens to share the package's name.
  • Version comparison for upgradePath and minCvss filtering uses a generic leading-numeric comparator, not each ecosystem's own version scheme (PEP 440, semver, Maven versioning, ...). Pre-release suffixes and epoch markers are ignored.
  • The OSV.dev API is queried live; the Actor stores no advisory data between runs.

Support

For reproducible issues, open an issue from the Actor page and include the Apify run ID, sanitized input, and expected result. Do not include API tokens or private data.