Software Security Intelligence - CVE, KEV & GitHub Advisories avatar

Software Security Intelligence - CVE, KEV & GitHub Advisories

Pricing

$10.00 / 1,000 advisory extracteds

Go to Apify Store
Software Security Intelligence - CVE, KEV & GitHub Advisories

Software Security Intelligence - CVE, KEV & GitHub Advisories

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.

Pricing

$10.00 / 1,000 advisory extracteds

Rating

0.0

(0)

Developer

Oaida Adrian

Oaida Adrian

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

Share

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?

SourceWhat it contributesEndpoint
NVD (NIST)CVSS score + vector, CWE weakness class, affected products with version ranges, references, analysis statusservices.nvd.nist.gov/rest/json/cves/2.0
CISA KEVknownExploited flag, date added, remediation due date, required action, ransomware-campaign usecisa.gov/.../known_exploited_vulnerabilities.json
GitHub Advisory Databasepackage + ecosystem, vulnerable version range, first patched version, EPSS exploitation probability, workaround textapi.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 targetResult
NVD /rest/json/cves/2.0?cveId=…, ?keywordSearch=…&pubStartDate=…, ?hasKev, ?kevStartDate=…200, real vulnerabilities payloads
CISA KEV catalogue200, 1.72 MB, 1,711 exploited CVEs
api.github.com/advisories?ecosystem=npm&affects=lodash200, 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 lookupscveIds 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 lookupsecosystem: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

{
"products": ["openssl"],
"packages": ["npm:lodash", "pip:requests"],
"cveIds": ["CVE-2021-44228"],
"onlyKnownExploited": false,
"publishedSince": "30d",
"maxResultsPerQuery": 10
}
OptionTypeDescription
productsstring[]Keywords swept against the NVD CVE API — openssl, apache log4j, fortinet. One search per keyword inside the window (default ["openssl"]).
packagesstring[]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"]).
cveIdsstring[]Exact CVE identifiers, fetched directly; the publication window does not apply (default []).
onlyKnownExploitedbooleanKeep only CISA KEV entries — confirmed exploited in the wild. Applied in the NVD query (hasKev) and again after the join (default false).
publishedSincestringFreshness 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.
applyDateWindowToPackagesbooleanAlso window package lookups by publication date — the scheduled-monitor mode. Off by default so a package lookup returns its full advisory history (default false).
severitiesstring[]Keep only CRITICAL / HIGH / MEDIUM / LOW / UNKNOWN. Empty keeps all (default []).
minCvssScorenumberDrop rows scoring below this. Rows with no score at all are dropped too when this is > 0 (default 0).
maxResultsPerQueryintegerNVD page size, and GitHub page size per package (default 25, max 100).
includeGithubAdvisoriesbooleanTurn off to run on NVD + CISA KEV alone — handy when the keyless GitHub quota is already spent (default true).
includeUnreviewedAdvisoriesbooleanGitHub advisories are reviewed by default; unreviewed ones are machine-imported and their stated severity can disagree with their own CVSS vector (default false).
includeWithdrawnAdvisoriesbooleanWithdrawn (retracted upstream) advisories are dropped by default, so a retraction is never published as live intelligence; the count appears in SUMMARY.withdrawnDropped (default false).
nvdApiKeystring (secret)Optional. Keyless NVD allows 5 requests / 30 s; a free key allows 50 / 30 s.
githubTokenstring (secret)Optional. Keyless GitHub API allows 60 requests / hour per IP; any token allows 5,000 / hour.

Output — one item per advisory

FieldDescription
advisoryIdCVE id when there is one, otherwise the GHSA id
advisoryTypeCVE or GHSA
cveId, ghsaIdsIdentifiers, joined
titleCISA vulnerability name, else the GHSA summary, else an excerpt of the description
descriptionFull English description (NVD preferred, longer of the two after a join)
severity, severitySourceCRITICALUNKNOWN, and whether NVD or GitHub stated it
severityFromCvssScoreThe severity implied by the CVSS score — published alongside the stated one because sources sometimes disagree with themselves
cvssScore, cvssVector, cvssVersionBest available metric (v4 > v3.1 > v3.0 > v2, primary metric preferred)
cvssScoresEvery available base score, keyed v4 / v3.1 / v3.0 / v2
epssPercentage, epssPercentileEPSS exploitation probability (from GitHub, when present)
published, lastModifiedUTC ISO-8601
kevDateAddedDate the CVE entered the CISA KEV catalogue
nvdStatusAnalyzed, Awaiting Analysis, Undergoing Analysis, Modified, Rejected
cweIds, cweNamesWeakness classes (deduplicated, order preserved)
affectedProducts[{vendor, product, part, cpe, vulnerable, versionStartIncluding, versionStartExcluding, versionEndIncluding, versionEndExcluding}]
affectedProductsCount, affectedProductsTruncatedTrue CPE count and whether the list above was capped (100 rows)
affectedPackages[{ecosystem, name, vulnerableVersionRange, firstPatchedVersion, vulnerableFunctions}]
knownExploitedtrue / 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, patchUrlsWhether a fix is published, and the patch/advisory links (NVD Patch tags, commit links, GHSA fixed-version data)
hasWorkaroundGHSA description documents a workaround
references, referenceCount, referencesTruncatedCitations (capped at 30, with the true total)
sourcesWhich of NVD / CISA KEV / GitHub Advisory Database contributed
sourceUrls{nvd, github, cisaKev}
githubAdvisory{type, reviewedAt, nvdPublishedAt, withdrawnAt, sourceCodeLocation} when a GHSA matched
withdrawntrue when the advisory was retracted upstream (rows are dropped unless you ask for them)
queries, matchedOnWhich input produced the row, and how (product, cveId, package)
severityRank, scrapedAtSort helper and extraction timestamp

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

Worked example

Input:

{ "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):

{
"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):

{
"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

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:

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 optionsMaximum 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.