# yaml-language-server: $schema=../../../../schema/control.schema.json id: CB-DEB-PKG-008 title: Leave no security update pending finding: title: Security updates are available but not installed description: Packages with published security fixes are still installed in their vulnerable version. status: active profiles: [core] risk: severity: medium assessment: automated tags: [apt, updates] description: | `apt-get -s dist-upgrade` simulates an upgrade from the local package lists and shows, for each package, the version and origin of the update. Updates coming from the Debian security suite fix vulnerabilities. The result is only as fresh as the package lists, refreshed by `apt-get update` or `apt-daily.timer`. rationale: | An available security update means the vulnerability is public and a fix exists, which is when exploitation is most likely. Checking for pending security updates catches systems where automatic updates are disabled, broken, or blocked by a held package or a dependency change. impact: | None for the check, which changes nothing. Installing updates restarts the services concerned. notes: | The check fails on pending security updates and on package lists older than `{{ max_lists_age }}` days, since stale lists hide pending updates. Other pending updates (point release, backports) are only listed in the evidence. The check does not run `apt-get update`: refresh the lists first for an up-to-date answer. parameters: - name: max_lists_age type: integer description: Maximum age of the newest package list before the check fails. unit: days default: 7 minimum: 1 maximum: 90 audit: manual: | 1. Run `apt-get update`. 2. Run `apt-get -s dist-upgrade | grep '^Inst' | grep -i security`. It must print nothing. checks: - id: pending engine: shell description: Updates pending in the local package lists, and the age of these lists. spec: script: | s=$(LC_ALL=C apt-get -s -o Debug::NoLocking=1 dist-upgrade 2>/dev/null) || { echo "apt-get simulation failed"; exit 3; } all=$(printf '%s\n' "$s" | grep -c '^Inst ') sec=$(printf '%s\n' "$s" | grep '^Inst ' | grep -E '\(.*(Debian-Security|-security)' | awk '{ print $2 }') nsec=$(printf '%s' "$sec" | grep -c .) newest=$(find /var/lib/apt/lists -maxdepth 1 -name '*Release' -printf '%T@\n' 2>/dev/null | sort -n | tail -1) age=999 [ -n "$newest" ] && age=$(( ($(date +%s) - ${newest%.*}) / 86400 )) echo "$all pending, $nsec security ($(printf '%s' "$sec" | head -20 | tr '\n' ' ')), lists $age days old" [ "$nsec" -eq 0 ] && [ "$age" -le "$CB_MAX_LISTS_AGE" ] remediation: manual: | Run `apt-get update` then `apt-get dist-upgrade` (or `unattended-upgrade` for security updates only), during a maintenance window if services must not restart. Reboot when the kernel, libc or systemd were updated (`/run/reboot-required` exists). If a package is held (`apt-mark showhold`), find out why before releasing it. references: - title: apt-get(8), Debian manual pages url: https://manpages.debian.org/trixie/apt/apt-get.8.en.html publisher: Debian kind: vendor-doc accessed: 2026-10-18 - title: Debian Security FAQ url: https://www.debian.org/security/faq publisher: Debian kind: vendor-doc accessed: 2026-10-18 - title: ANSSI-BP-028 v2.0 - Recommandations de configuration d'un système GNU/Linux (R61) url: https://messervices.cyber.gouv.fr/documents-guides/fr_np_linux_configuration-v2.0.pdf publisher: ANSSI kind: guide accessed: 2026-10-18 mappings: - framework: anssi-linux framework_version: "2.0" id: R61 relation: partial note: R61 asks for a regular update process; this control checks its result for security updates. - framework: nist-800-53r5 framework_version: "5.1.1" id: SI-2 relation: related - framework: cis-debian-12 framework_version: "2.0.0" id: "1.2.2.1" relation: partial note: Only security updates make the check fail; other pending updates are reported. - framework: cis-debian-13 framework_version: "1.1.0" id: "1.2.2.1" relation: partial note: Only security updates make the check fail; other pending updates are reported. threats: - framework: mitre-attack id: T1190 - framework: mitre-attack id: T1068 - framework: cwe id: CWE-1395 related_controls: - id: CB-DEB-PKG-007 type: related authors: - name: Alice github: Sn0wAlice verified: - date: 2026-10-18 by: Sn0wAlice versions: ["12"] environment: Proxmox VM, Debian 12 genericcloud image, kernel 6.1.0-54-cloud-amd64 notes: "Passes on up-to-date VM; fails after downgrading libexpat1 below its security version and with lists older than max_lists_age; passes again after upgrade." - date: 2026-10-18 by: Sn0wAlice versions: ["13"] environment: Proxmox VM, Debian 13 genericcloud image, kernel 6.12.113+deb13-cloud-amd64 notes: "Passes on up-to-date VM; fails after downgrading libexpat1 below its security version and with lists older than max_lists_age; passes again after upgrade." introduced_in: 0.1.0 created: 2026-10-18 updated: 2026-10-18