Skip to content

CodisTech/cve-patch-watch

Repository files navigation

cve-patch-watch

Tells the difference between a SIEM CVE alert that's stale and one that's actually actionable right now — and pages only on the transition that matters: the moment an upstream patch becomes available for a vulnerability you're still exposed to.

The problem it solves

A vulnerability scanner (here, Wazuh's vuln-detector) keeps its own copy of the distro CVE feed, and that copy lags the distribution's security database by hours to days. Two failure modes fall out of that lag:

  • False alarm fatigue — the scanner keeps firing on a CVE you already patched, because its feed hasn't caught up. The alert is noise.
  • Silent actionability — a CVE that had no fix yesterday gets one today, but nothing tells you the patch dropped. The alert looks the same as it did when there was nothing you could do.

cve-patch-watch reconciles the scanner's findings against the distribution's authoritative per-release fix data and resolves that ambiguity.

How it works

Hourly:

  1. Pull all active High/Critical CVE findings from the SIEM indexer, across every agent.

  2. For each Ubuntu finding, fetch the authoritative per-CVE JSON from ubuntu.com/security/cves/<id>.json (disk-cached, 12h TTL).

  3. Compare the agent's installed package version against Ubuntu's fixed version for that release, using dpkg --compare-versions — the canonical Debian version-ordering, not string compare.

  4. Bucket each finding:

    Bucket Meaning Action
    PATCHED released & installed ≥ fixed none — stale scanner alert
    REAL_FIX released & installed < fixed apt upgrade now
    PENDING needed / needs-triage real exposure, no upstream fix yet
    OTHER not-affected, missing DB entry, non-Ubuntu agent, pkg-name mismatch ignore
  5. Diff against the previous run's state and notify only on transitions:

    • PENDING → REAL_FIX"the patch just dropped" (the signal you want)
    • (nothing) → REAL_FIX — a new exposure that already has a fix
    • REAL_FIX → (gone) — resolved (informational; only mentioned when there's already news worth sending)

A run with no transitions is silent. The state file persists the REAL_FIX and PENDING sets between runs so the diff is stable.

Design choices

  • High/Critical only. The indexer holds thousands of findings, most of them historical or dedupe noise. Filtering severity at the query aligns the tool with what the SIEM already pages on, and keeps a warm-cache run to seconds instead of minutes.
  • dpkg --compare-versions, not string compare. Debian version strings (epochs, ~rc, ubuntu1.4 vs ubuntu1.10) don't sort lexically. Shelling out to dpkg borrows the distro's own comparator and removes a whole class of off-by-one version bugs.
  • Notify on transitions, not on state. Alerting on the current set would re-page every hour for the same unfixed CVEs. Alerting on the change surfaces exactly the two moments a human cares about: a fix landing, or a new fixable exposure appearing.
  • Cache with TTL. A cold run does ~1k CVE lookups; the 12h on-disk cache makes subsequent runs near-instant and is polite to the upstream API.

Configuration

All credentials and paths come from the environment — nothing is hardcoded. See cve-patch-watch.env.example:

Var Purpose
INDEXER_URL / INDEXER_USER / INDEXER_PASS SIEM indexer connection
TG_BOT_TOKEN / TG_CHAT_ID Telegram delivery
STATE_DIR where state + the Ubuntu CVE cache live

Deployed as a systemd oneshot + hourly timer (.service / .timer), with the env file at mode 600.

Scope / non-goals

  • Doesn't auto-apply patches — it tells you when, you decide.
  • Ubuntu agents only; non-Ubuntu agents (e.g. BSD-based appliances) skip silently.
  • Kernel meta-package name normalization (linux-image-X.Y.Z-genericlinux-generic) is a known gap — those land in OTHER for now.
  • Medium-severity CVEs are filtered out at the query.

Stack

Python 3 (standard library + requests) · dpkg · systemd · Ubuntu Security CVE API · a Wazuh/OpenSearch-style indexer as the finding source.

About

Reconciles SIEM CVE findings against the distro CVE database — pages only when a patch actually becomes available.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages