Skip to content

feat: enrich findings with EPSS scores from FIRST.org - #1053

Merged
sonukapoor merged 3 commits into
mainfrom
feature/epss-scores
Aug 27, 2026
Merged

feat: enrich findings with EPSS scores from FIRST.org#1053
sonukapoor merged 3 commits into
mainfrom
feature/epss-scores

Conversation

@sonukapoor

Copy link
Copy Markdown
Collaborator

Adds EPSS (Exploit Prediction Scoring System) enrichment from FIRST.org to all findings. After the OSV pass, CVE aliases are batch-fetched in a single API call and each finding gets an epssScores array with probability and percentile values.

  • Compact terminal: highest EPSS shown in the top-3 urgent findings block
  • Verbose terminal: new EPSS column in the full findings table
  • HTML report: EPSS subheading in each finding's expandable detail panel (single and multi-folder)
  • JSON output: full epssScores array per finding
  • Skipped in offline mode and for GHSA-only findings; fails gracefully without affecting scan results

Closes #1052

New src/epss/client.ts: fetchEpssScores() batch-fetches EPSS scores
from the FIRST.org API (https://api.first.org/data/v1/epss) for a list
of CVE IDs. Returns a Map<string, EpssScore> keyed by uppercase CVE ID.
Degrades gracefully (returns empty Map) on any network/parse failure.
Filters out non-CVE IDs (GHSA-only findings) before calling the API.

Added EpssScore type to src/types.ts and the optional epssScores field
to Finding so the scanner can attach per-finding EPSS data.

11 unit tests in tests/epss.test.ts cover: empty input, GHSA-only
filtering, correct parse, uppercase normalization, deduplication, non-200
status, network throws, malformed JSON, malformed epss values, and
missing data array.
scanner.ts: after the OSV + remediation pass, call enrichWithEpssScores()
to batch-fetch FIRST.org EPSS data for all CVE IDs in one HTTP request.
Skipped in offline mode and when no CVE aliases are present. Failures
degrade silently (empty map, no scan error).

formatters.ts: serializeFinding() now includes epssScores (array or null)
so the JSON output and HTML report data both carry EPSS automatically.

printers.ts: verbose compact block shows the highest-EPSS score per
finding, e.g. "EPSS: 97.6% exploitation probability - CVE-2021-44228
(top 0.03% of all CVEs)".

html-reporter.ts: finding detail panel includes a new EPSS subheading
with the same highest-score display when scores are available. The
tooltip explains what EPSS measures.
@sonukapoor
sonukapoor force-pushed the feature/epss-scores branch from 2a6768f to 6950322 Compare August 27, 2026 21:33
@sonukapoor
sonukapoor merged commit ecf04fa into main Aug 27, 2026
6 checks passed
@sonukapoor
sonukapoor deleted the feature/epss-scores branch August 27, 2026 21:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: enrich findings with EPSS scores from FIRST.org

1 participant