CISA KEV Vulnerability Prioritization After the Weekly Bulletin

CISA KEV vulnerability prioritization pipeline filtering exploited vulnerabilities into a patch queue

CISA ended its Weekly Vulnerability Bulletin on September 28, 2026. The change is more than a newsletter retirement: it reflects a broader shift away from patch queues driven almost entirely by CVSS scores and toward decisions based on active exploitation, exposure, exploit automation, and technical impact.

For defenders, the practical replacement is not a different weekly PDF. It is a repeatable workflow that combines the CISA Known Exploited Vulnerabilities (KEV) Catalog, vendor advisories, asset inventory, and business context. This guide explains how to build that workflow and includes a safe lab for monitoring the official KEV JSON feed.

What changed on September 28

In a notice sent on September 16, CISA said it would discontinue the weekly Vulnerability Bulletin on September 28. The bulletin had provided broad, CVSS-oriented vulnerability summaries. CISA now points subscribers toward three sources: the KEV Catalog, CISA cybersecurity alerts and advisories, and the CVE program. It also recommends consulting vendor and service-provider advisories directly.

The change aligns with Binding Operational Directive 26-04, released June 10, 2026. The directive applies to U.S. federal civilian agencies, but its prioritization model is useful well beyond government: assess public exposure, KEV status, exploit automation, and technical impact instead of treating a severity score as the complete risk decision.

Why CVSS alone creates the wrong queue

CVSS describes technical severity under defined conditions. It does not tell you whether attackers are using a vulnerability today, whether the affected service is exposed, whether compensating controls block the attack path, or whether the asset supports a critical business process.

A critical score can belong to software that is not deployed. A lower-scored issue can sit on an internet-facing appliance with reliable exploitation and privileged impact. If both enter the same “critical within 30 days” queue, the scoring system hides the difference that matters to operations.

KEV provides a strong signal because inclusion means CISA has evidence that exploitation has occurred in the wild. It is intentionally narrower than the full CVE universe. That makes it valuable for prioritization, but not sufficient as a complete vulnerability-management program.

What KEV does—and does not—prove

  • It proves an exploitation signal: CISA has added the CVE after applying its KEV inclusion criteria.
  • It does not prove exposure: you must still map the affected product and version to your assets and attack paths.
  • It does not replace vendor guidance: the vendor advisory remains the source for affected versions, patches, workarounds, and prerequisites.
  • Absence is not safety: a new or targeted exploit may not yet appear in KEV, and many consequential weaknesses are never added.
  • The due date is not a universal SLA: KEV remediation dates are mandatory for covered federal agencies. Other organizations should set deadlines from their own risk and exposure.

A practical KEV-first prioritization model

A useful pipeline enriches the external exploitation signal with internal facts. Start with four lanes rather than one giant severity backlog.

Priority 0: exploited and reachable

Escalate immediately when a KEV entry maps to an affected, internet-reachable asset or to an attack path available to an untrusted network. Confirm the product and version, review the vendor advisory, preserve relevant logs, apply the update or documented mitigation, and validate that exposure is removed. Edge devices, identity systems, remote-access services, hypervisors, management planes, and externally reachable applications deserve special attention.

Priority 1: exploited but not directly reachable

Keep KEV-matched internal assets near the front of the queue. “Internal” is not the same as unreachable: phishing, compromised endpoints, VPN access, partner connectivity, and lateral movement can expose services that are absent from an internet scan. Use network controls and identity boundaries to determine whether the exploit path is realistically blocked.

Priority 2: exposed with credible exploitability

A vulnerability may merit urgent action before KEV inclusion when the asset is public, exploitation is automatable, the technical impact is high, and credible vendor or researcher evidence exists. Track CISA alerts, vendor advisories, and trustworthy research alongside the catalog.

Priority 3: backlog with verified ownership

Everything else still needs an owner, a decision, and a review date. Reduce noise by closing findings for software that is not installed, recording accepted exceptions, and grouping fixes by product and maintenance window. A smaller, evidence-backed backlog is easier to defend than thousands of untouched scanner rows.

Build the data pipeline

CISA publishes the catalog as JSON, CSV, and a machine-readable JSON Schema. CISA also maintains an official GitHub mirror, which is useful for change history and resilient automation.

  1. Ingest: fetch the official feed on a regular cadence and retain the previous snapshot.
  2. Validate: reject malformed data and alert on missing required fields instead of silently producing an empty queue.
  3. Match: correlate vendor, product, and CVE identifiers with the asset inventory, SBOM data, scanner results, and cloud inventory.
  4. Enrich: add internet reachability, exploit-path evidence, asset criticality, identity privilege, and compensating controls.
  5. Assign: create a ticket with an owner, remediation or mitigation action, deadline, and evidence requirements.
  6. Verify: confirm the affected version is gone or the attack path is blocked; do not close a ticket solely because a deployment job returned success.

If you are developing a broader intelligence function, pair this pipeline with the collection and prioritization practices in our guide to building a cyber threat intelligence program. Teams that want to productionize the collection step can also adapt the controls in our Bash security automation guide.

Hands-on lab: monitor the KEV JSON feed safely

This lab only downloads and analyzes public catalog data. It does not scan, exploit, patch, or modify any production system.

Prerequisites and isolation

  • Python 3.9 or newer
  • Outbound HTTPS access to www.cisa.gov
  • A disposable working directory; no administrator privileges are required
mkdir -p "$HOME/kev-lab"
cd "$HOME/kev-lab"
python3 --version

Create the monitor

Save the following as kev_watch.py. It validates the key fields used by the report, compares the live feed with the previous snapshot, highlights entries added during a configurable lookback, and exports a CSV for ticketing or SIEM ingestion.

#!/usr/bin/env python3
import argparse
import csv
import json
import sys
import urllib.request
from datetime import date, datetime, timedelta
from pathlib import Path

URL = "https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json"
REQUIRED = {"cveID", "vendorProject", "product", "vulnerabilityName",
            "dateAdded", "dueDate", "requiredAction"}

def read_feed(source):
    if source.startswith(("https://", "http://")):
        request = urllib.request.Request(
            source, headers={"User-Agent": "KEV-monitor/1.0"}
        )
        with urllib.request.urlopen(request, timeout=30) as response:
            return json.load(response)
    return json.loads(Path(source).read_text(encoding="utf-8"))

def iso_day(value):
    return datetime.strptime(value, "%Y-%m-%d").date()

parser = argparse.ArgumentParser(description="Create a local CISA KEV change report")
parser.add_argument("--source", default=URL, help="HTTPS URL or local JSON file")
parser.add_argument("--days", type=int, default=14, help="lookback for dateAdded")
parser.add_argument("--snapshot", default="kev-previous.json")
parser.add_argument("--csv", default="kev-priority.csv")
args = parser.parse_args()

try:
    data = read_feed(args.source)
    records = data.get("vulnerabilities")
    if not isinstance(records, list):
        raise ValueError("feed has no vulnerabilities array")
    for index, item in enumerate(records):
        missing = REQUIRED - set(item)
        if missing:
            raise ValueError(f"record {index} missing: {sorted(missing)}")
except Exception as exc:
    print(f"ERROR: refusing to process invalid feed: {exc}", file=sys.stderr)
    raise SystemExit(1)

snapshot = Path(args.snapshot)
old_ids = set()
if snapshot.exists():
    previous = json.loads(snapshot.read_text(encoding="utf-8"))
    old_ids = {item["cveID"] for item in previous.get("vulnerabilities", [])}

today = date.today()
recent_cutoff = today - timedelta(days=args.days)
due_cutoff = today + timedelta(days=14)

rows = []
for item in records:
    added = iso_day(item["dateAdded"])
    due = iso_day(item["dueDate"])
    is_new = bool(old_ids) and item["cveID"] not in old_ids
    if is_new or added >= recent_cutoff or due <= due_cutoff:
        rows.append({
            "cve": item["cveID"],
            "vendor": item["vendorProject"],
            "product": item["product"],
            "date_added": item["dateAdded"],
            "due_date": item["dueDate"],
            "new_since_snapshot": "yes" if is_new else "no",
            "ransomware_use": item.get("knownRansomwareCampaignUse", "Unknown"),
            "required_action": item["requiredAction"],
        })

rows.sort(key=lambda row: (row["new_since_snapshot"] != "yes", row["due_date"]))
with open(args.csv, "w", newline="", encoding="utf-8") as handle:
    writer = csv.DictWriter(handle, fieldnames=rows[0].keys() if rows else [
        "cve", "vendor", "product", "date_added", "due_date",
        "new_since_snapshot", "ransomware_use", "required_action"
    ])
    writer.writeheader()
    writer.writerows(rows)

snapshot.write_text(json.dumps(data, indent=2), encoding="utf-8")
print(f"Validated records: {len(records)}")
print(f"New since previous snapshot: {sum(r['new_since_snapshot'] == 'yes' for r in rows)}")
print(f"Priority report rows: {len(rows)}")
print(f"Wrote: {args.csv} and {args.snapshot}")

Run and inspect the report

chmod 700 kev_watch.py
./kev_watch.py --days 14
head -n 6 kev-priority.csv

The first run has no earlier snapshot, so New since previous snapshot will be zero. The live record and report counts vary as CISA updates the catalog. Run the command again after a later feed update to identify newly added CVEs. A successful run prints the validated record count, delta count, report-row count, and the two files written.

Troubleshooting

  • HTTP 403 or proxy error: use the official GitHub mirror’s raw JSON URL as --source, or download the CISA file through your approved proxy and pass the local path.
  • TLS certificate failure: repair the host trust store or proxy certificate chain. Do not disable certificate verification in the script.
  • Validation failure: compare the feed against CISA’s current JSON Schema. Treat a schema change as an operational alert, not an empty “all clear.”
  • Product matching gaps: normalize vendor and product names and prefer scanner or SBOM CVE mappings over free-text matching alone.

Cleanup

cd ..
rm -rf kev-lab

Detection and response checks for a KEV match

When a catalog entry matches an asset, patching is only one workstream. Exploitation may have preceded disclosure or your maintenance window. Open a parallel investigation proportional to exposure and impact:

  • Confirm the affected version and whether the vulnerable feature is enabled.
  • Review the vendor advisory for indicators, exploit prerequisites, fixed releases, and workarounds.
  • Search edge, application, identity, EDR, and network telemetry for the relevant time window.
  • Look for new accounts, unexpected configuration changes, persistence, credential access, and suspicious outbound connections.
  • Preserve evidence before reimaging or making changes that erase useful artifacts.
  • After remediation, rescan the asset and test the control from the same network path an attacker could use.

Metrics that show whether the process works

A dashboard should measure decisions and exposure, not just the number of open CVEs. Useful indicators include time from KEV addition to asset match, time to mitigate internet-reachable KEVs, percentage of KEV findings with a confirmed owner, age of exceptions, and time from deployment to independent verification.

Also track false matches and inventory gaps. If the feed arrives within minutes but product ownership takes days to resolve, faster polling will not improve the outcome. The bottleneck is asset context.

Conclusion

The retirement of CISA’s Weekly Vulnerability Bulletin is a useful forcing function. A weekly severity list was easy to consume but easy to mistake for a strategy. A KEV-first pipeline makes exploitation evidence central, then combines it with reachability, automation, technical impact, and business context.

Start small: ingest the official feed, validate it, map it to owned assets, and create a clearly assigned response for each match. Then add exposure data and verification. The goal is not to patch fewer vulnerabilities blindly; it is to act first where a real attack is most likely to succeed.

Primary sources

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *