Build a weekly CVE triage workflow with CISA KEV, EPSS and CVSS
This article was first published on the Rokkhe blog on Hashnode. It was drafted with AI assistance and reviewed and edited by the Rokkhe team; all commands and sources were checked against CISA, FIRST and NVD documentation.
A one-hour operational pass you can run every Monday, using official feeds only. 15 November 2026, Asia/Dhaka. By the Rokkhe research team.
Most teams do not fail at “finding CVEs.” They fail at deciding which ones to do this week. Three public signals help, and they do not measure the same thing: CISA’s Known Exploited Vulnerabilities (KEV) catalog records vulnerabilities with reliable evidence of exploitation in the wild, and a clear remediation action. EPSS, from FIRST, estimates the probability that a CVE will be exploited in the next 30 days. CVSS describes severity (how bad a successful exploit can be), not whether anyone is exploiting it.
This post is a weekly workflow: fetch, join, ticket. It complements the existing Rokkhe briefing on how to prioritize vulnerabilities with CISA KEV, EPSS and CVSS; it does not replace that briefing, and it does not invent a success rate for the method.
Do not use this workflow to discuss or publish embargoed research. If a draft is under vendor embargo, it stays out of the queue.
TL;DR
- If a CVE is in KEV and you run the product, treat it as a priority this week, even when EPSS is low. FIRST says that explicitly.
- Use EPSS for the large majority of CVEs that are not in KEV.
- Use CVSS to understand impact once you already know a CVE is relevant, not as the only sort key.
- The commands below only read public APIs. They do not patch anything by themselves.
- After you patch a KEV item, hunt for signs it was used before the fix. A patch does not prove the box was clean.
Three signals, three different questions
CISA maintains the KEV catalog so organisations can prioritize vulnerabilities that have already been used. CISA also publishes BOD 26-04, Prioritizing Security Updates Based on Risk (issued 10 June 2026), which carries the KEV criteria forward and tells federal civilian agencies to prioritize using exposure, KEV status, exploit automation and technical impact. You do not have to be a federal agency for the catalog to be useful. CISA encourages every organisation to watch it.
FIRST’s “Using EPSS” guidance is careful about what the score is: a calibrated probability of observed exploitation in the next 30 days, not a severity score and not a complete risk score. A low EPSS on a KEV-listed CVE is not a contradiction. KEV says exploitation has already been seen. EPSS says the current signal looks like CVEs that are rarely exploited in the next month.
FIRST’s rule of thumb: when a CVE is on KEV, treat it as a priority regardless of EPSS. Use EPSS for everything KEV does not cover.
CVSS remains useful for impact: a network-exploitable, no-user-interaction vulnerability is a different change window than a local issue that needs an existing account. It is a poor only-sort, because a “critical” CVE with no exploitation evidence and no instance in your estate should not beat a “high” KEV item you actually run.
A fourth, unglamorous signal sits underneath all three: do we have this product, in this version, on a reachable network? If the answer is no, log it and stop. If the answer is “we do not know,” the first ticket is inventory, not a patch.
Pull this week’s KEV additions
CISA publishes the catalog as a JSON feed. The following command only downloads a public file:
curl -fsSL \
'https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json' \
-o /tmp/kev.json
# Newest dateAdded values first. Adjust the slice as you like.
jq -r '.vulnerabilities | sort_by(.dateAdded) | reverse | .[:20] | .[] | [.dateAdded, .cveID, .vendorProject, .product, .shortDescription] | @tsv' /tmp/kev.json
For a weekly pass, filter to additions since last Monday (use your date):
SINCE=2026-11-09 # replace with last week's cutoff, in UTC dates as the feed uses them
jq -r --arg since "$SINCE" '.vulnerabilities[] | select(.dateAdded >= $since) | [.dateAdded, .cveID, .vendorProject, .product, .requiredAction] | @tsv' /tmp/kev.json
Keep the dateAdded field in the ticket. A brand-new KEV entry is a stronger “do it this week” signal than an entry that has been in the catalog for years; FIRST notes that the force of a KEV listing degrades if there is no other evidence of ongoing activity. You still need to know whether you ever patched it.
Look up EPSS and CVSS for the CVEs you actually run
Do not look up EPSS for the entire catalog on the first pass. Look it up for (a) this week’s KEV additions that match your inventory, and (b) the rest of your scanner findings that are not in KEV. The official EPSS API is documented by FIRST:
# Example form only. Replace the CVE list with IDs you actually need.
curl -fsSL 'https://api.first.org/data/v1/epss?cve=CVE-2021-40438&pretty=true'
Several IDs at once:
IDS='CVE-2021-40438,CVE-2019-16759'
curl -fsSL "https://api.first.org/data/v1/epss?cve=${IDS}&pretty=true" \
| jq -r '.data[] | [.cve, .epss, .percentile, .date] | @tsv'
Record the date of the EPSS value in the ticket. Scores are published daily and they move. A number without a date is not reproducible.
For CVSS, use the National Vulnerability Database or the CNA’s advisory, and write down the version of CVSS (3.1 or 4.0) and the vector, not only the number. If NVD analysis is still pending, say so. Do not invent a score.
# NVD 2.0 API, public CVE. Respect NVD's published rate limits.
# Replace the CVE ID.
curl -fsSL 'https://services.nvd.nist.gov/rest/json/cves/2.0?cveId=CVE-2021-40438' \
| jq '.vulnerabilities[0].cve.metrics'
Join the three sources in a spreadsheet or a small script: cve, in_kev, kev_date, epss, epss_date, cvss, product, in_inventory, decision. The join key is the CVE ID. The decision is human.
A simple decision order you can put in a ticket
Use this order, not a single score:
- In our inventory, and in KEV - this week, unless you already completed the KEV-required action and recorded it. Assign an owner and a due date.
- In our inventory, not in KEV, high EPSS - this week or next, after the KEV items. Write the EPSS date and percentile in the ticket so a reviewer can see why it jumped the queue.
- In our inventory, not in KEV, lower EPSS, high impact (CVSS / reachability) - scheduled work, not ignored. Internet-facing and unauthenticated still matter even when the forecast is quiet.
- Not in inventory - close as “does not apply,” with the product name and the date you checked.
- Unknown inventory - a ticket for the asset owners, not a silent skip.
A ticket template you can paste:
Title: [KEV|EPSS|CVSS] CVE-YYYY-NNNNN - product - version
Signals: KEV yes/no (dateAdded), EPSS x.xx on YYYY-MM-DD (percentile), CVSS x.x (version, vector, source)
Where: host or image, version, how we know
Exposure: internet-facing / internal / unknown
Action: patch to version … / mitigate / remove
Hunt required: yes if KEV or confirmed exploitation
Owner / due:
Checked on: (Asia/Dhaka date)
Do not attach unofficial exploit code to the ticket. Link the vendor advisory and the KEV entry.
Hunt after you patch, when the catalog says it was exploited
A KEV listing means someone has already used the vulnerability, somewhere. Patching stops new use of that hole. It does not remove an operator who arrived last week. CISA’s KEV remediation guidance for agencies, and the way CISA writes product-specific alerts, consistently separates “apply the vendor update” from “look for evidence of use.”
When a vendor or a CISA alert publishes indicators, use those indicators. When they ask you to look for unexpected privileged sessions, unexpected scripts, or gaps in logs, do that before you declare the ticket done, and where the guidance says so, collect volatile evidence before a reboot that would wipe it.
A minimal hunt, if no better advisory exists yet:
- Version evidence: what was running before the change window?
- Authentication and admin-session logs around the exposure window.
- New local accounts, unexpected scheduled tasks, unexpected outbound connections from the host.
- Gaps in logs that should have been continuous.
If you find a match, stop calling it a patch ticket. It is an incident. Preserve evidence, follow your incident process, and rotate credentials that the system could have exposed.
Post 3 in this series covers leaked secrets; post 10 covers writing a detection so the next one is less of a surprise.
A one-hour Monday workflow
Set a recurring 60-minute block. The times below assume Asia/Dhaka.
- 0-10 minutes. Download the KEV feed. List entries with
dateAddedsince last Monday. Diff against last week’s saved copy so you notice removals and changes too. - 10-25 minutes. Mark each new KEV item against inventory (CMDB, package list, container SBOM, or a simple spreadsheet of internet-facing products). Anything unmatched goes to “unknown - ask owner.”
- 25-40 minutes. For scanner findings not in KEV, pull EPSS and record dates. Sort that remainder by EPSS, then by exposure and CVSS.
- 40-55 minutes. Open or update tickets using the template. Close last week’s items only if the patch and any required hunt are done.
- 55-60 minutes. Save
/tmp/kev.json(or your filtered TSV) to the week’s folder, with the date, so next Monday has a baseline.
The feature-CVE briefings in this programme are the public-facing cousin of step 2: one exploited or widely deployed CVE, explained. This workflow is the internal queue that decides which of those become work.
FAQ
Does a low EPSS on a KEV CVE mean CISA made a mistake? No. FIRST describes this as two different questions: history versus a 30-day forecast. Prioritize the KEV item if you run the product.
Is EPSS a risk score we can put in a dashboard as the only column? FIRST says it is not a complete risk score. Use it with inventory, exposure and impact.
Do we have to follow BOD 26-04 if we are not a US federal agency? The directive applies to federal civilian executive branch agencies. The KEV catalog and the idea of prioritizing exploited and exposed systems are still useful to everyone else.
Why not sort everything by CVSS? Because CVSS does not say whether the vulnerability is being used, or whether you have the product. It still belongs on the ticket.
Can we automate the tickets? Yes, the fetch and join can be a script. The inventory match and the “is this actually reachable?” decision should stay reviewable by a person.
Sources
- CISA, Known Exploited Vulnerabilities catalog
- CISA, Reducing the significant risk of known exploited vulnerabilities
- CISA, BOD 26-04: Prioritizing Security Updates Based on Risk
- FIRST, Using EPSS
- FIRST, EPSS API (example calls checked 15 November 2026)
Related reading on rokkhe.com/blog: How to prioritize vulnerabilities with CISA KEV, EPSS and CVSS.
Next in the series Lock down Amazon S3 and IAM with least privilege and Block Public Access. Previous: Find leaked secrets in Git and rotate them before they are used.
Rokkhe is an AI pentesting and security-operations workspace. Learn more at rokkhe.com.
Comments
No comments yet. Start the discussion.