# Dependency Vulnerability Advisor — Find Fixes, Not Just CVEs (`alaudinburki/dependency-vulnerability-advisor`) Actor

Check your dependencies against the OSV database and get the exact version to upgrade to. Returns an upgrade plan — one target version per package that clears the most findings at once — instead of a list of CVE IDs you still have to research.

- **URL**: https://apify.com/alaudinburki/dependency-vulnerability-advisor.md
- **Developed by:** [alaudin burki](https://apify.com/alaudinburki) (community)
- **Categories:** Developer tools, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Dependency Vulnerability Advisor — Find the Fix, Not Just the CVE

Every scanner tells you that you're vulnerable. That's the easy half — and it leaves you with a list of
CVE IDs and an afternoon of cross-referencing to work out **what to actually upgrade to**.

The fixed version is sitting right there in the advisory data those scanners already read. This returns
it, as an **upgrade plan**.

Source: **OSV.dev** (Google's open-source vulnerability database). **No API key, no login, no anti-bot.**

### What makes the output different

A normal scanner:

> `lodash@4.17.15` — GHSA-29mw-wpgm-hmr9, GHSA-35jh-r3h4-6jhm, GHSA-p6mc-m468-83gw…

This:

> **Upgrade lodash 4.17.15 → 4.17.21 (clears 6 of 6).**

And where a clean fix isn't possible, it says so instead of pretending:

> **Upgrade django 3.2.1 → 3.2.25** (stays on 3.x, clears **48 of 61**).
> The remaining 13 need **5.2.17** — a major-version upgrade.

That second line is the whole point. Telling someone on Django 3.2 to "just upgrade to 5.2" is
technically the only way to clear everything and completely useless as advice. You get **both**: the bump
you can do this afternoon, and the honest cost of finishing the job.

### What you get

| Field | Description |
|---|---|
| `package` · `currentVersion` · `ecosystem` | What you're running |
| **`fixedVersion`** | The version that fixes *this* finding |
| **`upgradeTarget`** | One target that clears everything for this package |
| **`safeTarget`** | The highest fix on your **current major version** |
| **`clearedBySafeTarget`** | How many findings that safer bump resolves |
| **`needsMajorUpgrade`** | Whether finishing the job crosses a major version |
| **`recommendation`** | "Upgrade now" / "this week" / "next opportunity" / "low priority" |
| `severity` · `severityRank` · `cve` · `cwe` | Standard triage fields |
| `advisoryUrl` · `summary` · `published` | The advisory itself |

Supports **npm, PyPI, Go, Maven, NuGet, Packagist, RubyGems, crates.io, Pub, Hex**.

### Input

```json
{
  "packages": ["npm:lodash@4.17.15", "pypi:django@3.2.1", "npm:@babel/core@7.0.0"],
  "minSeverity": "MODERATE"
}
```

Or point it at a manifest:

```json
{ "manifestUrls": ["https://raw.githubusercontent.com/you/repo/main/package-lock.json"] }
```

**A lockfile is best** — it lists what you actually run. A `package.json` range like `^4.0.0` doesn't say
which version is installed, so ranges are resolved to their base version and that's an approximation.

### Sample output

```json
[
  {
    "package": "lodash",
    "ecosystem": "npm",
    "currentVersion": "4.17.15",
    "vulnerabilityId": "GHSA-29mw-wpgm-hmr9",
    "cve": "CVE-2020-28500",
    "severity": "MODERATE",
    "summary": "Regular Expression Denial of Service (ReDoS) in lodash",
    "fixedVersion": "4.17.21",
    "upgradeTarget": "4.17.21",
    "needsMajorUpgrade": false,
    "recommendation": "Upgrade at the next opportunity: lodash 4.17.15 → 4.17.21.",
    "advisoryUrl": "https://github.com/advisories/GHSA-29mw-wpgm-hmr9"
  }
]
```

The full per-package plan is in the **`UPGRADE_PLAN`** key-value record.

### Typical uses

- **Before a release** — one run, one list of bumps.
- **Scheduled audit** — new advisories land daily against versions that were clean yesterday. This is a
  monitoring job, not a one-off.
- **Inherited codebase** — find out how bad it is, and what the cheapest safe move is.
- **Client reports** — an upgrade plan is a sellable deliverable; a CVE list isn't.

### Pricing

**$2.00 / 1,000 findings** (`$0.002` per result), plus a near-zero start fee. A typical project audit is
well under a dollar. Never charged beyond `maxItems`.

### ⚠️ Read before you act

- **A finding means your version is in a vulnerable range — not that you're exploitable.** It doesn't
  prove your code reaches the affected function. Triage before you panic.
- **Only pinned versions can be checked.** A range in `package.json` is resolved to its base version,
  which may not be what's installed. Use a lockfile for accuracy.
- **OSV sometimes lists a fix in a version line that was never released** (a "not fixed here"
  placeholder). Where fixes span release lines, `allFixedVersions` shows every one so you can sanity-check
  the target before installing it.
- **Advisories are filtered to your exact package.** One advisory often covers a whole family (`lodash`,
  `lodash-es`, `lodash.template`) with *different* fixed versions — a real bug found during testing, where
  a sibling package's version could otherwise leak into your recommendation.

### FAQ

- **Do I need an API key?** No.
- **Which ecosystems?** npm, PyPI, Go, Maven, NuGet, Packagist, RubyGems, crates.io, Pub, Hex.
- **Does it scan private repos?** No — it reads public manifest URLs or an explicit package list. Nothing
  is uploaded.
- **Is it the same as `npm audit`?** Same database family, different output: this gives you the
  cross-ecosystem upgrade plan, including the "stay on your major version" option that `npm audit` doesn't.

### Related actors

- **npm Package Info** — maintenance health and abandonment risk for a package.
- **GitHub Repository Scraper** — activity and health of the upstream project.

# Actor input Schema

## `packages` (type: `array`):

Explicit packages as ecosystem:name@version, e.g. npm:lodash@4.17.15 or pypi:django@3.2.1. Scoped npm names work: npm:@babel/core@7.0.0.

## `manifestUrls` (type: `array`):

Public URLs to a package.json, package-lock.json or requirements.txt — raw.githubusercontent.com links work well. A lockfile is best: it lists what you actually run, not a range.

## `defaultEcosystem` (type: `string`):

Used when a package is given without an ecosystem prefix.

## `minSeverity` (type: `string`):

Only return findings at or above this level.

## `concurrency` (type: `integer`):

How many packages to query at once.

## `maxItems` (type: `integer`):

Hard cap on findings returned. You are never charged beyond this.

## `checkExploitation` (type: `boolean`):

Cross-reference every finding against CISA KEV (confirmed exploited in the wild) and EPSS (probability of exploitation in the next 30 days). This is what turns a list of findings into triage — a MODERATE CVE being actively exploited matters more than a CRITICAL one nobody is using.

## Actor input object example

```json
{
  "packages": [
    "npm:lodash@4.17.15",
    "npm:axios@0.21.0",
    "pypi:django@3.2.1"
  ],
  "defaultEcosystem": "npm",
  "minSeverity": "ANY",
  "concurrency": 8,
  "maxItems": 5000,
  "checkExploitation": true
}
```

# Actor output Schema

## `results` (type: `string`):

Vulnerabilities with the version that fixes each one.

## `upgradePlan` (type: `string`):

One target version per package, ordered by severity.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "packages": [
        "npm:lodash@4.17.15",
        "npm:axios@0.21.0",
        "pypi:django@3.2.1"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("alaudinburki/dependency-vulnerability-advisor").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "packages": [
        "npm:lodash@4.17.15",
        "npm:axios@0.21.0",
        "pypi:django@3.2.1",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("alaudinburki/dependency-vulnerability-advisor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "packages": [
    "npm:lodash@4.17.15",
    "npm:axios@0.21.0",
    "pypi:django@3.2.1"
  ]
}' |
apify call alaudinburki/dependency-vulnerability-advisor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,alaudinburki/dependency-vulnerability-advisor"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/UF1V2BurYnSYl3hB7/builds/tsP40EpvUa9BGobAI/openapi.json
