Scanning servers for missing security updates

Updated November 2026

The fastest scan is the one your package manager already has: it reads the vendor’s own advisory data and knows about backported fixes. Use it first on every host. Add osv-scanner, Trivy or Grype for what the package manager cannot see: application dependencies, container images and software you installed by hand.

Two kinds of check

Package manager and vendor data
Tools such as dnf updateinfo, zypper lp, debsecan and pkg audit compare installed packages with the vendor’s advisories. They answer “which fix am I missing?” correctly, even when the vendor patched an old version number. Always refresh the package lists first, or the result is stale.
General scanners
osv-scanner, Trivy and Grype list packages (OS packages, lockfiles, binaries) and match them against vulnerability databases. They are best for images and app dependencies. On a host they can disagree with the vendor. When they do, the vendor’s advisory or security tracker decides.

Debian: debsecan

debsecan downloads Debian’s security tracker data and lists the vulnerabilities that affect the installed packages. Give it the release code name (Debian 13 is trixie). --only-fixed requires --suite.

sudo apt install debsecan

debsecan --suite trixie --only-fixed                    # vulnerabilities with a fix in the archive
debsecan --suite trixie --only-fixed --format packages  # just the binary package names
debsecan --suite trixie                                 # everything, including unfixed issues

Each summary line shows the CVE ID and the binary package, then notes in brackets: fixed (a fixed package is in the archive), remotely exploitable, the Debian urgency (low, medium or high urgency) and obsolete (the package is no longer in the archive, so remove it). Lines without fixed have no Debian fix yet. Debian tracks source packages, so every binary package built from a vulnerable source is listed, including documentation packages. Install the fixes with sudo apt update && sudo apt upgrade.

Debian and Ubuntu: apt

sudo apt update
apt list --upgradable                          # all pending updates
apt list --upgradable 2>/dev/null | grep -- -security   # only those from the security archive

Each line reads package/suite new-version architecture [upgradable from: old-version]. A suite ending in -security (for example trixie-security or noble-security) means a security fix. The man page spells the option --upgradeable; both spellings work. Debian fixes some low-impact issues in point releases rather than the security archive, so a clean -security list does not prove you have every fix. debsecan shows those too.

RHEL family: dnf updateinfo

RHEL, Rocky Linux, AlmaLinux and Fedora repositories carry advisory metadata (“updateinfo”). DNF can filter by type, severity and CVE:

sudo dnf updateinfo summary                     # counts: Security (Critical/Important/Moderate/Low), Bugfix...
sudo dnf updateinfo list --security             # one line per missing security advisory
sudo dnf updateinfo list --sec-severity=Critical
sudo dnf updateinfo list --security --with-cve  # show CVE IDs instead of advisory IDs
sudo dnf updateinfo info RHSA-XXXX:NNNN         # details of one advisory
sudo dnf updateinfo list --cve=CVE-2024-6387    # am I missing the fix for this CVE?

A list line has three columns: the advisory ID, the type and severity (for example Important/Sec.) and the package NEVRA, the exact name-version-release-architecture that fixes it. No output means no missing advisories for enabled repositories. dnf check-update exits with code 100 when any update is available, which is handy in scripts. Fedora 41 and later use DNF5, where the same commands work as dnf advisory list --security (updateinfo is kept as an alias).

SUSE: zypper

sudo zypper refresh
zypper lp                              # list-patches: all needed patches
zypper lp -g security                  # security patches only
zypper lp -g security --severity critical,important
zypper lp --cve=CVE-2024-6387          # patches for one CVE
zypper pchk; echo $?                   # patch-check: 100 = patches needed, 101 = security patches needed

Each patch shows its category (security, recommended, optional...) and severity (critical, important, moderate, low). Options that take an optional value, like --cve, need =.

Alpine

apk update
apk list --upgradable

apk has no security-only filter and Alpine publishes no formal advisories. Its secdb data maps fixed versions to CVEs, and Trivy and Grype use it for Alpine hosts and images.

Arch Linux: arch-audit

sudo pacman -S arch-audit
arch-audit -u        # only packages that already have a fixed version
arch-audit -c        # include CVE numbers
arch-audit -r        # also list packages that depend on vulnerable ones

arch-audit reads the Arch security tracker. For each package it lists the CVEs, the risk level and, if one exists, the version to update to. Packages without a fix are still listed unless you use -u. Fix them with a full upgrade: sudo pacman -Syu.

FreeBSD and OpenBSD

# FreeBSD packages: download the vulnerability database, then check
pkg audit -F
pkg audit -F -r      # also list packages that depend on vulnerable ones

# FreeBSD base system (traditional install), as root
freebsd-update fetch
freebsd-update updatesready; echo $?   # 2 = nothing to install

# OpenBSD base system, as root
syspatch -c          # list patches not yet installed

pkg audit checks installed packages against VuXML, the database of port vulnerabilities. Each finding names the package and the issue, with a reference to the advisory. Flaws in the base system are published as FreeBSD Security Advisories and, on a traditional install, fixed with freebsd-update. FreeBSD 15.0 also offers “pkgbase”, a technology preview in which the base system is installed and managed entirely with pkg.

App dependencies: osv-scanner

Packages your apps pull in through Composer, npm, pip, Go or Cargo are not tracked by the OS package manager. osv-scanner (version 2) reads lockfiles and checks them against OSV.dev:

osv-scanner scan source -r /srv/app                       # find lockfiles recursively
osv-scanner scan source -L /srv/app/composer.lock         # one lockfile
osv-scanner scan image registry.example.com/app:1.4       # a container image

The table shows the OSV URL, CVSS score, ecosystem, package, installed version, fixed version (-- if there is none yet) and the source file. Exit code 0 means no known vulnerabilities, 1 means vulnerabilities found, and 128 means it found no packages to scan, which usually means a wrong path.

Filesystems and images: Trivy and Grype

# Trivy: OS packages on this host, vulnerabilities only
trivy rootfs --pkg-types os --scanners vuln /
# Trivy: a project directory (uses lockfiles such as package-lock.json)
trivy fs /srv/app
# Trivy: an image, only High/Critical issues that have a fix
trivy image --severity HIGH,CRITICAL --ignore-unfixed registry.example.com/app:1.4

# Grype: an image, only fixed issues, exit code 2 if any High or worse
grype registry.example.com/app:1.4 --only-fixed --fail-on high
# Grype: a directory
grype dir:/srv/app
grype db update      # refresh the vulnerability database

Scanners are software too. In March 2026 attackers published a malicious Trivy release (0.69.4) and repointed tags of the trivy-action and setup-trivy GitHub Actions (CVE-2026-33634, GHSA-69fq-xp46-6x23). CISA added it to the KEV catalog. Install scanners from the vendor’s signed packages, verify signatures, pin CI actions to a full commit SHA, and run scanners without secrets they do not need.

RHEL and Ubuntu: OpenSCAP

OpenSCAP’s oscap evaluates OVAL data, a machine-readable list of advisories, and writes an HTML report. On RHEL 8 and 9, as root:

dnf install openscap-scanner bzip2
curl -sL https://security.access.redhat.com/data/oval/v2/RHEL9/rhel-9.oval.xml.bz2 | bzip2 -d > rhel-9.oval.xml
oscap oval eval --report vulnerability.html rhel-9.oval.xml

Use RHEL8/rhel-8 in the URL on RHEL 8. In the output, a definition marked true means the advisory was issued but the update is not installed. RHEL 10 has no OVAL feed: Red Hat put OVAL v2 in maintenance mode and points to its CSAF and VEX files instead. On RHEL 10 use dnf updateinfo or a scanner that reads CSAF/VEX data. OpenSCAP itself stays in RHEL 10 and can still read OVAL files.

Ubuntu publishes OVAL data per release. After installing the openscap-scanner package:

wget https://security-metadata.canonical.com/oval/com.ubuntu.$(lsb_release -cs).usn.oval.xml.bz2
bunzip2 com.ubuntu.$(lsb_release -cs).usn.oval.xml.bz2
oscap oval eval --report report.html com.ubuntu.$(lsb_release -cs).usn.oval.xml

Where Lynis fits

Lynis is an open-source auditing tool for Linux and Unix (sudo lynis audit system). It checks hardening and configuration, and one of its tests (PKGS-7392) flags packages with pending security updates. It is a good second opinion, not a replacement for the checks above.

Make it routine

Sources