Skip to content

Repository files navigation

Simple CVE Tracker

A self-hosted server that watches public CVE feeds for vulnerabilities you actually care about. You keep a watchlist of vendors, products, or keywords, it polls the public CVE sources on a schedule, and it emails you when something on your watchlist lands. Built for MSP technicians and small IT teams who need to know about the CVEs relevant to their stack without babysitting a feed all day.

Preview

Simple CVE Tracker dashboard in dark and light themes
Dark and light themes

Features

  • Keyword and vendor:product watchlist matching, with an optional CVSS threshold
  • CISA KEV (Known Exploited Vulnerabilities) flagging
  • NVD CVSS and FIRST.org EPSS enrichment
  • Coalesced email alerts with a retry queue for failed sends
  • Web dashboard showing sync health for every data source
  • SQLite storage, no external database to run or manage
  • All data stays local: no telemetry, no third-party analytics

Quick start (Docker)

docker compose up -d

Open http://localhost:8080. On first run the app downloads about 90 days of CVE history; this takes a few minutes and progress is shown in the UI. Data persists in a named Docker volume, so it survives container rebuilds.

The first run needs about 2 GB of free disk space temporarily for the download; ongoing usage afterward is under 100 MB.

Run from source

Requires Python 3.11+.

pip install -r requirements.txt
python -m simple_cve_tracker serve

By default the server binds to 127.0.0.1:8080. Pass --host 0.0.0.0 to expose it beyond localhost, and --port to change the port.

Install as a systemd service (Linux / Raspberry Pi)

This installs the app under a dedicated service account so it runs independent of any user login. Extract the release tarball, cd into it, then run the install script as root:

tar xzf simple-cve-tracker-vX.Y.Z.tar.gz
cd simple-cve-tracker-vX.Y.Z
sudo ./deploy/install.sh

The script probes ports 8080 through 8090 and uses the first one that is free. Pass --port N to force a specific port instead, for example if you already know 8080 is taken:

sudo ./deploy/install.sh --port 8091

If your chosen port is already in use by another service (Pi-hole's web UI uses 8080, for example), pick a different one. The app now refuses to start with a clear error instead of failing oddly if the port turns out to be unavailable.

The installation keeps application code, persistent data, and the Python environment separate:

  • /opt/simple-cve-tracker/app contains the active release.
  • /opt/simple-cve-tracker/data contains the database and downloaded source data.
  • /opt/simple-cve-tracker/venv contains the Python virtual environment.

To update, extract the new release tarball and run the same install command from that extracted directory. The installer stages and replaces app, rebuilds venv, and preserves data. On the first update from an older installation that stored release files directly in /opt/simple-cve-tracker, it removes only known legacy release files after the replacement service has started successfully. Other files are left alone.

Manual install: the script above just automates these steps, which you can also run by hand if you want more control:

sudo useradd --system --create-home --home-dir /opt/simple-cve-tracker sct
sudo install -d -o sct -g sct /opt/simple-cve-tracker/{app,data,venv}
# From the extracted release root, copy the release into app/:
sudo cp -a . /opt/simple-cve-tracker/app/
sudo chown -R sct:sct /opt/simple-cve-tracker/app
sudo -u sct python3 -m venv /opt/simple-cve-tracker/venv
sudo -u sct /opt/simple-cve-tracker/venv/bin/pip install -r /opt/simple-cve-tracker/app/requirements.txt
sudo cp /opt/simple-cve-tracker/app/deploy/simple-cve-tracker.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now simple-cve-tracker

Configuration

Everything is configured in the web UI settings page: poll intervals, retention, SMTP, and the optional NVD API key.

The data directory and two secrets can be set by environment variables:

Variable Purpose
SCT_DATA_DIR Data directory location
SCT_SMTP_PASSWORD SMTP password; overrides and locks the UI field
SCT_NVD_API_KEY NVD API key; overrides and locks the UI field

For SMTP, use an app password rather than your account password. Email alerts are optional; the app works with alerts turned off.

Updating

Docker: pull or rebuild the image and run docker compose up -d again. The named volume keeps your data.

From source / systemd: extract the new release tarball, then rerun sudo ./deploy/install.sh from that extracted directory. The installer replaces the application directory and rebuilds its virtual environment while the data directory remains in place.

Verify a release

Releases are packed on GitHub-hosted runners with signed build provenance.

gh attestation verify simple-cve-tracker-vX.Y.Z.tar.gz \
  --repo JDE-Projects/Simple-CVE-Tracker \
  --signer-repo JDE-Projects/Build-Tools
sha256sum -c simple-cve-tracker-vX.Y.Z.tar.gz.sha256

The --signer-repo flag is required because the release workflow lives in a separate repository.

Data sources

License

Released under the PolyForm Internal Use License 1.0.0: free to use and modify within your own organization. See THIRD-PARTY-LICENSES.txt for notices on bundled fonts and runtime dependencies.

About

A simple tool for looking up and tracking CVEs relevant to your infrastructure.

Resources

Security policy

Stars

Watchers

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages