# Software Security Intelligence - CVE, KEV & GitHub Advisories (`darknezz/software-security-intelligence`) Actor

One row per vulnerability, joined across the NVD CVE 2.0 API, the CISA Known Exploited Vulnerabilities catalogue and GitHub Security Advisories: CVSS, CWE, affected products and version ranges, package fix versions, and whether the flaw is exploited in the wild. No API key.

- **URL**: https://apify.com/darknezz/software-security-intelligence.md
- **Developed by:** [Oaida Adrian](https://apify.com/darknezz) (community)
- **Categories:** Developer tools, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$10.00 / 1,000 advisory extracteds

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

## Software Security Intelligence — CVE + CISA KEV + GitHub Advisories

One JSON row per vulnerability, **joined across three open, keyless, citable sources**, so a single
record answers the question a buyer actually asks about a product, a vendor or a dependency:

> **Is this software being exploited in the wild — and is there a fix?**

| Source | What it contributes | Endpoint |
|---|---|---|
| **NVD** (NIST) | CVSS score + vector, CWE weakness class, affected products with version ranges, references, analysis status | `services.nvd.nist.gov/rest/json/cves/2.0` |
| **CISA KEV** | `knownExploited` flag, date added, **remediation due date**, required action, ransomware-campaign use | `cisa.gov/.../known_exploited_vulnerabilities.json` |
| **GitHub Advisory Database** | package + ecosystem, vulnerable version range, **first patched version**, EPSS exploitation probability, workaround text | `api.github.com/advisories` |

**No API key is required for any of the three.** Optional NVD / GitHub keys raise the rate ceilings and make
wide sweeps faster — see the input table.

### Why this Actor

The retired `g2-reviews-scraper` slot never really sold star ratings; it sold *vendor due diligence*. For
software, the hard version of that question is answered by advisories, not reviews: CVE identifiers, CVSS
vectors, affected version ranges and the CISA exploited-in-the-wild list are the evidence a security review,
a compliance check, an SBOM gate or a procurement decision actually cites.

Nothing else in this account touches vulnerabilities, and it is deliberately complementary to
`sec-edgar-filings-scraper` (financial filings): together they cover the two diligence halves — *can they
deliver?* and *is their software safe to run?*

Feasibility was proven **before** the Actor was written, from Apify datacenter IPs with **no proxy and no
key** (`dc-probe`, internal tool):

| Probe target | Result |
|---|---|
| NVD `/rest/json/cves/2.0?cveId=…`, `?keywordSearch=…&pubStartDate=…`, `?hasKev`, `?kevStartDate=…` | 200, real `vulnerabilities` payloads |
| CISA KEV catalogue | 200, 1.72 MB, 1,711 exploited CVEs |
| `api.github.com/advisories?ecosystem=npm&affects=lodash` | 200, real `ghsa_id` records |

Probe runs: `U0iaJmkfyXFZZh2bS` (source discovery) and `b6DyB7OzV0GZy9V5l` (exact request shapes).

### What it does

1. Fetches the **CISA KEV catalogue once** per run (one request, ~1.7 MB) and indexes it by CVE.
2. **Product / vendor sweeps** — each keyword becomes one NVD CVE search inside the `publishedSince` window
   (`hasKev` added when `onlyKnownExploited` is on, `noRejected` always, so rejected CVEs don't pollute the
   output).
3. **Exact CVE lookups** — `cveIds` are fetched by identifier and ignore the publication window; each one
   is also looked up on GitHub, so a CVE-only record still gains the package name and the first patched
   version (that is how `CVE-2021-44228` picks up `GHSA-jfh8-c2jp-5v3q` and the `log4j-core` fix).
4. **Package lookups** — `ecosystem:name` (optionally `ecosystem:name@version`) is resolved through the GitHub
   Advisory Database, which is where version ranges and *first patched version* live.
5. **Joins everything on the identifier** — one row per CVE, carrying the KEV block, every matching GHSA
   advisory, the package fix versions and the NVD CPE list. GHSA rows with no CVE stay as their own row
   rather than being dropped.
6. Charges **one event per emitted row** and writes a `SUMMARY` key-value record (matches, emits, per-source
   fetch counts, KEV catalogue version, GitHub quota left, errors, notes).

NVD's keyless quota is 5 requests / 30 s, so the Actor **paces itself automatically** (6.5 s between NVD
calls, 1 s with a key) and backs off on 403/429/5xx instead of hammering.

### Input

```json
{
  "products": ["openssl"],
  "packages": ["npm:lodash", "pip:requests"],
  "cveIds": ["CVE-2021-44228"],
  "onlyKnownExploited": false,
  "publishedSince": "30d",
  "maxResultsPerQuery": 10
}
```

| Option | Type | Description |
|--------|------|-------------|
| `products` | string\[] | Keywords swept against the NVD CVE API — `openssl`, `apache log4j`, `fortinet`. One search per keyword inside the window (default `["openssl"]`). |
| `packages` | string\[] | `ecosystem:name` for the GitHub Advisory Database — `npm:lodash`, `pip:requests`, `maven:org.apache.logging.log4j:log4j-core`. Add `@version` (`npm:lodash@4.17.18`) to ask "am I affected at this version?" (default `["npm:lodash"]`). |
| `cveIds` | string\[] | Exact CVE identifiers, fetched directly; the publication window does not apply (default `[]`). |
| `onlyKnownExploited` | boolean | Keep only CISA KEV entries — confirmed exploited in the wild. Applied in the NVD query (`hasKev`) and again after the join (default `false`). |
| `publishedSince` | string | Freshness window for product sweeps: `30d`, `12h`, `2w`, `1m`, or an ISO date such as `2026-08-01`. `all` disables it (default `30d`). Look-backs longer than **120 days** are split into 120-day NVD chunks automatically (up to ~2 years) — NVD refuses a longer range outright. |
| `applyDateWindowToPackages` | boolean | Also window package lookups by publication date — the scheduled-monitor mode. Off by default so a package lookup returns its full advisory history (default `false`). |
| `severities` | string\[] | Keep only `CRITICAL` / `HIGH` / `MEDIUM` / `LOW` / `UNKNOWN`. Empty keeps all (default `[]`). |
| `minCvssScore` | number | Drop rows scoring below this. Rows with no score at all are dropped too when this is > 0 (default `0`). |
| `maxResultsPerQuery` | integer | NVD page size, and GitHub page size per package (default `25`, max `100`). |
| `includeGithubAdvisories` | boolean | Turn off to run on NVD + CISA KEV alone — handy when the keyless GitHub quota is already spent (default `true`). |
| `includeUnreviewedAdvisories` | boolean | GitHub advisories are `reviewed` by default; unreviewed ones are machine-imported and their stated severity can disagree with their own CVSS vector (default `false`). |
| `includeWithdrawnAdvisories` | boolean | Withdrawn (retracted upstream) advisories are dropped by default, so a retraction is never published as live intelligence; the count appears in `SUMMARY.withdrawnDropped` (default `false`). |
| `nvdApiKey` | string (secret) | Optional. Keyless NVD allows 5 requests / 30 s; a free key allows 50 / 30 s. |
| `githubToken` | string (secret) | Optional. Keyless GitHub API allows 60 requests / hour per IP; any token allows 5,000 / hour. |

### Output — one item per advisory

| Field | Description |
|-------|-------------|
| `advisoryId` | CVE id when there is one, otherwise the GHSA id |
| `advisoryType` | `CVE` or `GHSA` |
| `cveId`, `ghsaIds` | Identifiers, joined |
| `title` | CISA vulnerability name, else the GHSA summary, else an excerpt of the description |
| `description` | Full English description (NVD preferred, longer of the two after a join) |
| `severity`, `severitySource` | `CRITICAL`…`UNKNOWN`, and whether NVD or GitHub stated it |
| `severityFromCvssScore` | The severity implied by the CVSS score — published alongside the stated one because sources sometimes disagree with themselves |
| `cvssScore`, `cvssVector`, `cvssVersion` | Best available metric (v4 > v3.1 > v3.0 > v2, primary metric preferred) |
| `cvssScores` | Every available base score, keyed `v4` / `v3.1` / `v3.0` / `v2` |
| `epssPercentage`, `epssPercentile` | EPSS exploitation probability (from GitHub, when present) |
| `published`, `lastModified` | UTC ISO-8601 |
| `kevDateAdded` | Date the CVE entered the CISA KEV catalogue |
| `nvdStatus` | `Analyzed`, `Awaiting Analysis`, `Undergoing Analysis`, `Modified`, `Rejected`… |
| `cweIds`, `cweNames` | Weakness classes (deduplicated, order preserved) |
| `affectedProducts` | `[{vendor, product, part, cpe, vulnerable, versionStartIncluding, versionStartExcluding, versionEndIncluding, versionEndExcluding}]` |
| `affectedProductsCount`, `affectedProductsTruncated` | True CPE count and whether the list above was capped (100 rows) |
| `affectedPackages` | `[{ecosystem, name, vulnerableVersionRange, firstPatchedVersion, vulnerableFunctions}]` |
| `knownExploited` | `true` / `false`, or **`null`** when the CISA catalogue could not be fetched (unknown ≠ not exploited) |
| `kev` | `{dateAdded, dueDate, vendorProject, product, vulnerabilityName, shortDescription, requiredAction, knownRansomwareCampaignUse, forensicTriage, notes, cwes}` or `null` |
| `hasPatch`, `patchUrls` | Whether a fix is published, and the patch/advisory links (NVD `Patch` tags, commit links, GHSA fixed-version data) |
| `hasWorkaround` | GHSA description documents a workaround |
| `references`, `referenceCount`, `referencesTruncated` | Citations (capped at 30, with the true total) |
| `sources` | Which of `NVD` / `CISA KEV` / `GitHub Advisory Database` contributed |
| `sourceUrls` | `{nvd, github, cisaKev}` |
| `githubAdvisory` | `{type, reviewedAt, nvdPublishedAt, withdrawnAt, sourceCodeLocation}` when a GHSA matched |
| `withdrawn` | `true` when the advisory was retracted upstream (rows are dropped unless you ask for them) |
| `queries`, `matchedOn` | Which input produced the row, and how (`product`, `cveId`, `package`) |
| `severityRank`, `scrapedAt` | Sort helper and extraction timestamp |

Rows are sorted **known-exploited first, then by CVSS, then newest** — the order a triage queue wants.

### Worked example

Input:

```json
{ "products": ["openssl"], "packages": ["npm:lodash"], "cveIds": ["CVE-2021-44228"],
  "publishedSince": "30d", "maxResultsPerQuery": 10 }
```

Output — one row, three sources joined, real values from cloud run **`dyasSwCaXeqT2L53P`** (build 0.1.4,
21 rows emitted):

```json
{
  "advisoryId": "CVE-2021-44228",
  "advisoryType": "CVE",
  "cveId": "CVE-2021-44228",
  "ghsaIds": ["GHSA-jfh8-c2jp-5v3q"],
  "title": "Apache Log4j2 Remote Code Execution Vulnerability",
  "severity": "CRITICAL",
  "severitySource": "nvd",
  "severityFromCvssScore": "CRITICAL",
  "cvssScore": 10,
  "cvssVector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H",
  "cvssVersion": "3.1",
  "cvssScores": {"v3.1": 10, "v2": 9.3},
  "epssPercentage": 0.99999,
  "epssPercentile": 1,
  "published": "2021-12-10T10:15:09.143",
  "lastModified": "2026-08-11T19:33:44.513",
  "kevDateAdded": "2021-12-10",
  "nvdStatus": "Analyzed",
  "cweIds": ["CWE-20", "CWE-400", "CWE-502", "CWE-917"],
  "cweNames": ["Improper Input Validation", "Uncontrolled Resource Consumption",
               "Deserialization of Untrusted Data",
               "Improper Neutralization of Special Elements used in an Expression Language Statement ('Expression Language Injection')"],
  "affectedProductsCount": 396,
  "affectedProductsTruncated": true,
  "affectedPackages": [
    {"ecosystem": "maven", "name": "org.apache.logging.log4j:log4j-core",
     "vulnerableVersionRange": ">= 2.13.0, < 2.15.0", "firstPatchedVersion": "2.15.0"}
  ],
  "knownExploited": true,
  "kev": {
    "dateAdded": "2021-12-10",
    "dueDate": "2021-12-24",
    "vendorProject": "Apache",
    "product": "Log4j2",
    "knownRansomwareCampaignUse": "Known",
    "requiredAction": "For all affected software assets for which updates exist, the only acceptable remediation actions are: 1) Apply updates; OR 2) remove affected assets from agency networks. …"
  },
  "hasPatch": true,
  "patchUrls": ["https://github.com/apache/logging-log4j2/pull/608"],
  "references": [{"url": "http://packetstormsecurity.com/files/165225/…", "source": "security@apache.org",
                  "tags": ["Third Party Advisory", "VDB Entry"]}],
  "referenceCount": 75,
  "referencesTruncated": true,
  "sources": ["NVD", "GitHub Advisory Database", "CISA KEV"],
  "sourceUrls": {"nvd": "https://nvd.nist.gov/vuln/detail/CVE-2021-44228",
                 "github": "https://github.com/advisories/GHSA-jfh8-c2jp-5v3q",
                 "cisaKev": "https://www.cisa.gov/known-exploited-vulnerabilities-catalog"},
  "githubAdvisory": {"type": "reviewed", "reviewedAt": "2021-12-10T00:40:41+00:00",
                     "nvdPublishedAt": "2021-12-10T10:15:00+00:00", "withdrawnAt": null,
                     "sourceCodeLocation": "https://github.com/apache/logging-log4j2"},
  "withdrawn": false,
  "queries": ["CVE-2021-44228"],
  "matchedOn": ["cveId"]
}
```

That single row answers the buyer's question end to end: **CRITICAL 10.0, exploited in the wild (CISA KEV,
ransomware campaigns known, federal remediation was due 2021-12-24), 396 affected products, and the fix is
`log4j-core` 2.15.0.**

A package row instead carries the fix version — the "should I upgrade?" answer (same run):

```json
{
  "advisoryId": "CVE-2019-10744",
  "ghsaIds": ["GHSA-jf85-cpcp-j695"],
  "title": "Prototype Pollution in lodash",
  "severity": "CRITICAL",
  "cvssScore": 9.1,
  "cvssVector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:H",
  "epssPercentage": 0.05006,
  "kevDateAdded": null,
  "knownExploited": false,
  "affectedPackages": [
    {"ecosystem": "npm", "name": "lodash", "vulnerableVersionRange": "< 4.17.12",
     "firstPatchedVersion": "4.17.12"},
    {"ecosystem": "npm", "name": "lodash-es", "vulnerableVersionRange": "< 4.17.14",
     "firstPatchedVersion": "4.17.14"},
    {"ecosystem": "rubygems", "name": "lodash-rails", "vulnerableVersionRange": "< 4.17.12",
     "firstPatchedVersion": "4.17.12"}
  ],
  "hasPatch": true,
  "sources": ["GitHub Advisory Database"],
  "matchedOn": ["package"]
}
```

(Queries for a vendor keyword behave the same way — every CVE the sweep returns is KEV-joined; e.g. the
same run's `openssl` sweep returned `CVE-2026-63073`, CRITICAL 9.8, `knownExploited: false`.)

### Run it from your code or on a schedule

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("darknezz/software-security-intelligence").call(
    run_input={"packages": ["npm:lodash", "pip:requests"], "onlyKnownExploited": False},
    max_total_charge_usd=5.00,
)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    flag = "EXPLOITED" if item["knownExploited"] else "—"
    print(flag, item["severity"], item["advisoryId"], item["title"])
```

REST equivalent:

```bash
curl -X POST "https://api.apify.com/v2/acts/darknezz~software-security-intelligence/runs?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"products":["openssl"],"onlyKnownExploited":true,"publishedSince":"7d"}'
```

A nightly security-monitor pattern: schedule `{"products": ["<your vendor>"], "publishedSince": "1d",
"onlyKnownExploited": true}` and alert on any row. `max_total_charge_usd` (Console → *Run options* →
*Maximum cost per run*) caps spend: 200 advisories × $0.01 = **$2.00**.

### Pricing

Pay per event: **$0.01 per advisory row** (`advisory-extracted`, primary event), charged once per emitted
item — no charge for the KEV catalogue, for NVD pages that yield nothing, or for a filtered-out match.
**100 advisories ≈ $1.00; 1,000 ≈ $10.00.** The platform's `apify-actor-start` event applies once per run as
usual.

An advisory row is deliberately priced above a review row: every row is a three-source join carrying CVSS,
weakness class, affected version ranges, exploitation status and the patch, i.e. the record a security or
procurement decision is written against.

### FAQ

**Can I look back a full year?** Yes — `publishedSince: "365d"` is split into 120-day NVD chunks
automatically (NVD answers an empty `404` for any longer range, which is why the Actor chunks rather than
trusting a single request). Each chunk costs one NVD call, so a year-long sweep of one keyword is four
paced calls; the per-chunk match counts appear in the run log.

**Do I need an API key?** No — NVD, CISA and GitHub's advisory endpoint all answer keyless. Keys only raise
rate ceilings: a free NVD key (50 vs 5 requests / 30 s) speeds up wide product sweeps, and any GitHub token
(5,000 vs 60 requests / hour) removes the keyless quota ceiling for large package lists.

**What happens when the keyless GitHub quota runs out mid-run?** The Actor reports it, stops issuing GitHub
requests and still returns everything NVD and CISA produced; the remaining package queries are named in
`SUMMARY.errors` and `SUMMARY.notes`. Charges stop with the rows, so a throttled run costs less.

**What do `knownExploited: null` rows mean?** The CISA KEV catalogue could not be fetched on that run, so the
exploit status is genuinely unknown. The Actor never reports a false "not exploited" — `SUMMARY.errors`
names the failed call.

**Why does the publication window not apply to my package lookup?** A dependency question ("does lodash have
known vulnerabilities?") wants the full history. Set `applyDateWindowToPackages: true` when you want
"what was published since my last run" instead — that is the monitor mode.

**Why do I get fewer rows than `maxResultsPerQuery`?** It is a page size, not a quota: filters run after the
join, and `hasKev` / `noRejected` narrow the NVD query itself.

**Can I filter by package version?** Yes — `npm:lodash@4.17.18` asks the GitHub Advisory Database the exact
question "is this version affected?", which is the fastest way to gate a dependency bump.

**Why are some advisories missing that I can see on GitHub?** Two deliberate exclusions, both
overridable: unreviewed advisories (machine-imported, and their stated severity can contradict their own
CVSS vector — set `includeUnreviewedAdvisories: true`) and withdrawn advisories (retracted upstream —
set `includeWithdrawnAdvisories: true`). The withdrawn count is always reported in
`SUMMARY.withdrawnDropped`, so nothing disappears silently.

**Why does `severity` sometimes disagree with `cvssScore`?** Because the sources disagree: GitHub may state
`low` on an advisory whose own CVSS vector is 9.8. Both are published — `severity` (as stated) and
`severityFromCvssScore` (as scored) — rather than the Actor inventing a tie-break.

**What is `affectedProductsTruncated` for?** Some CVEs list hundreds of CPEs (a Chrome release, a kernel
subsystem). The row carries the first 100 with the true count alongside, so a buyer knows the list is a
sample rather than the whole picture.

**Is the data attributable?** Every row carries `sourceUrls` for NVD, the GitHub advisory and the CISA
catalogue, plus the original `references` with their tags — cite from those, not from this Actor's summary.

**Is this a vulnerability scanner?** No. It is an intelligence feed: it reports what is published about a
product, vendor or package. It does not probe your hosts or resolve your dependency tree.

### Limitations

- **One NVD page per query, one query per 120-day chunk.** NVD is paged internally and refuses date
  ranges longer than 120 days, so the Actor takes the first `maxResultsPerQuery` of each chunk and reports
  the true match count. A very broad keyword (e.g. "linux") is therefore a sample; use specific product
  words, or `cveIds`, for exactness. A look-back beyond ~2 years is capped, with a `SUMMARY.notes` entry
  saying so.
- **Two deliberate source-side exclusions, both overridable.** Unreviewed GitHub advisories (their stated
  severity can contradict their own CVSS vector) and withdrawn advisories (retracted upstream) are excluded
  by default; both counts are reported in `SUMMARY` so the omission is never silent.
- **CVE-keyed joins only.** KEV and NVD join on CVE id; GitHub advisories join on their CVE id, so a
  GHSA-only advisory (no CVE assigned) cannot carry a KEV flag by construction — it reports
  `knownExploited: false` and no `kev` block.
- **Keyless quotas are per-IP and shared.** The Apify datacenter IP pool is shared with everything else
  running there, so the 60/hour GitHub budget can already be partly spent when your run starts. The Actor
  surfaces the remaining quota rather than hiding it.
- **CISA KEV is US-federal-scoped.** It lists vulnerabilities with confirmed in-the-wild exploitation, but it
  is not exhaustive: a `false` flag means "not in CISA KEV", not "certainly unexploited". EPSS
  (`epssPercentage`) is included as a complementary probabilistic signal.
- **No CVSS v4 enrichment from GitHub.** NVD's v4 metrics are used when present; GitHub's v4 field is carried
  through as-is when populated.
- **Descriptions are carried whole.** They can be long (multi-KB for detailed advisories) — trim before
  feeding them to a model if you are paying by token.

# Actor input Schema

## `products` (type: `array`):

Keywords to sweep the NVD CVE API with, e.g. "openssl", "apache log4j", "fortinet". Each keyword becomes one CVE search inside the publishedSince window.

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

Software packages to check against the GitHub Advisory Database, written as ecosystem:name, e.g. "npm:lodash", "pip:requests", "maven:org.apache.logging.log4j:log4j-core". Append @version (e.g. "npm:lodash@4.17.18") to ask the sharper question "am I affected at this version?".

## `cveIds` (type: `array`):

Exact CVE identifiers to fetch directly, e.g. \["CVE-2021-44228"]. Exact lookups ignore the publishedSince window — you asked for that CVE.

## `onlyKnownExploited` (type: `boolean`):

Keep only vulnerabilities in CISA's Known Exploited Vulnerabilities catalogue — the ones confirmed exploited in the wild. Applied to the NVD query itself (hasKev) and again after the join.

## `publishedSince` (type: `string`):

Freshness window for product sweeps: a relative window ("30d", "12h", "2w", "1m") or an ISO date ("2026-08-01"). "all" disables the window. Default 30d suits a scheduled monitor. Exact CVE lookups always ignore it.

## `applyDateWindowToPackages` (type: `boolean`):

When on, package lookups are also limited to advisories published inside the publishedSince window — useful for a scheduled "what changed since last run" monitor. Off by default, so a package query returns its full advisory history (the "does this dependency have known vulnerabilities?" question).

## `severities` (type: `array`):

Keep only these severities, e.g. \["CRITICAL", "HIGH"] (valid values: CRITICAL, HIGH, MEDIUM, LOW, UNKNOWN). Empty keeps every severity, including UNKNOWN — CVEs with no CVSS score are still real vulnerabilities.

## `minCvssScore` (type: `number`):

Drop advisories scoring below this. Records that carry no CVSS score at all are dropped too when this is above 0 — set it to 0 (default) to keep unanalysed CVEs.

## `maxResultsPerQuery` (type: `integer`):

NVD page size / maximum CVEs returned per product sweep, and the GitHub page size per package (max 100).

## `includeGithubAdvisories` (type: `boolean`):

Look packages (and CVE ids) up in the GitHub Advisory Database. Turn off to run on NVD + CISA KEV alone — useful when you have already spent the keyless GitHub quota this hour.

## `includeUnreviewedAdvisories` (type: `boolean`):

GitHub advisories are 'reviewed' by default; unreviewed ones are machine-imported and their stated severity can disagree with their own CVSS vector. Turn this on to include them anyway.

## `includeWithdrawnAdvisories` (type: `boolean`):

Withdrawn (retracted upstream) advisories are dropped by default so a retraction is never published as live intelligence. Turn this on only for historical research.

## `nvdApiKey` (type: `string`):

Optional. The NVD API works without a key, paced at 5 requests / 30 s; a free NVD key raises that to 50 / 30 s and makes wide multi-product sweeps much faster.

## `githubToken` (type: `string`):

Optional. Keyless GitHub API access is capped at 60 requests / hour per IP; any token raises it to 5,000 / hour. The run reports the remaining quota in its SUMMARY and degrades gracefully when it runs out.

## Actor input object example

```json
{
  "products": [
    "openssl"
  ],
  "packages": [
    "npm:lodash"
  ],
  "cveIds": [],
  "onlyKnownExploited": false,
  "publishedSince": "30d",
  "applyDateWindowToPackages": false,
  "severities": [],
  "minCvssScore": 0,
  "maxResultsPerQuery": 25,
  "includeGithubAdvisories": true,
  "includeUnreviewedAdvisories": false,
  "includeWithdrawnAdvisories": false
}
```

# Actor output Schema

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

No description

## `advisoryId` (type: `string`):

No description

## `title` (type: `string`):

No description

## `severity` (type: `string`):

No description

## `cvssScore` (type: `string`):

No description

## `knownExploited` (type: `string`):

No description

## `kevDueDate` (type: `string`):

No description

## `published` (type: `string`):

No description

## `sourceUrl` (type: `string`):

No description

# 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 = {
    "products": [
        "openssl"
    ],
    "packages": [
        "npm:lodash"
    ],
    "cveIds": [],
    "severities": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("darknezz/software-security-intelligence").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 = {
    "products": ["openssl"],
    "packages": ["npm:lodash"],
    "cveIds": [],
    "severities": [],
}

# Run the Actor and wait for it to finish
run = client.actor("darknezz/software-security-intelligence").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 '{
  "products": [
    "openssl"
  ],
  "packages": [
    "npm:lodash"
  ],
  "cveIds": [],
  "severities": []
}' |
apify call darknezz/software-security-intelligence --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,darknezz/software-security-intelligence"
        }
    }
}
```

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/2ggMf976gbYrerYcf/builds/rS5FVt4m5MoFlBfBY/openapi.json
