# yaml-language-server: $schema=../../../../schema/control.schema.json id: CB-DEB-PKG-002 title: Download packages over HTTPS finding: title: APT downloads from repositories over an unencrypted protocol description: Anyone on the network path sees which packages and versions the system installs, and can delay or block its updates. status: active profiles: [core] risk: severity: low assessment: automated tags: [apt, repositories, https] description: | Each APT source entry names one or more URIs. The `https` method encrypts and authenticates the connection to the mirror; `http` and `ftp` do not. Entries using `mirror+file:` point to a local list of mirrors, whose URIs are checked too. rationale: | APT verifies the signature of the Debian archive whatever the transport, so HTTP does not let an attacker change packages. It still exposes the list of installed packages and their versions, which tells an attacker which vulnerabilities are left, and lets a network attacker serve stale but validly signed metadata until it expires, or block updates silently. HTTPS removes these exposures and is required for repositories that are not signed by their provider. impact: | The system needs the `ca-certificates` package and outbound HTTPS. Caching proxies such as apt-cacher-ng cannot cache HTTPS traffic they do not terminate: list their HTTP URIs in the `http_allowed_uris` parameter rather than weaken the other controls. notes: | The Debian 12 and 13 cloud images already use `https://deb.debian.org`. A system installed with the Debian installer uses `http://deb.debian.org`; the automated fix switches `deb.debian.org` and `security.debian.org` to HTTPS. Other mirrors may not offer HTTPS and are left to a human. setting: location: /etc/apt/sources.list, /etc/apt/sources.list.d/*.list, /etc/apt/sources.list.d/*.sources default_value: https on cloud images, http after a Debian installer setup recommended_value: "https (or a local method such as file:, cdrom:, copy:) for every URI, except those starting with: {{ http_allowed_uris }}" parameters: - name: http_allowed_uris type: list description: URI prefixes allowed over plain HTTP, for example a local apt-cacher-ng proxy (http://apt-cache.example.org:3142/). Empty means none. default: [] audit: manual: | Run `grep -rhiE '^[^#]*(http|ftp)://' /etc/apt/sources.list /etc/apt/sources.list.d/`, and read the files named after `mirror+file:` if any. Every URI must use `https` or a local method, or start with one of the allowed prefixes. checks: - id: uris engine: shell description: Transport of every URI of the enabled APT source entries, including mirror lists. spec: script: | files= for f in /etc/apt/sources.list /etc/apt/sources.list.d/*.list /etc/apt/sources.list.d/*.sources; do [ -f "$f" ] && files="$files $f" done [ -n "$files" ] || { echo "no APT source file"; exit 2; } # One line per entry: file:line, types, URIs, suites, ;option=value list (lowercase). # shellcheck disable=SC2086 entries=$(awk ' function flush() { if (st && en != "no") print src "\t" ty "\t" ur "\t" su "\t" op; st = 0; ty = ur = su = op = en = "" } FNR == 1 { flush(); d = FILENAME ~ /\.sources$/ } !d { sub(/#.*/, ""); if ($1 !~ /^deb(-src)?$/) next l = $0; o = ""; i = index(l, "["); j = index(l, "]") if (i && j > i) { o = substr(l, i + 1, j - i - 1); l = substr(l, 1, i - 1) " " substr(l, j + 1) } split(l, w, " "); gsub(/[ \t]+/, ";", o) print FILENAME ":" FNR "\t" w[1] "\t" w[2] "\t" w[3] "\t;" tolower(o); next } /^#/ { next } /^[ \t]*$/ { flush(); next } /^[ \t]/ { next } { if (!st) { st = 1; src = FILENAME ":" FNR } k = $0; sub(/:.*/, "", k); k = tolower(k); v = $0; sub(/^[^:]*:[ \t]*/, "", v) if (k == "types") ty = v; else if (k == "uris") ur = v; else if (k == "suites") su = v else if (k == "enabled") en = tolower(v) else op = op ";" k "=" tolower(v == "" ? "inline" : v) } END { flush() }' $files) bad=$(printf '%s\n' "$entries" | while IFS="$(printf '\t')" read -r src _ uris _ _; do for u in $uris; do case $u in mirror+file:*) p=$(printf '%s' "$u" | sed 's#^mirror+file:/*#/#') [ -f "$p" ] || { echo "$src: $u (missing mirror list)"; continue; } list=$(grep -v '^[[:space:]]*#' "$p" 2>/dev/null | awk '{ print $1 }') ;; *) list=$u ;; esac for m in $list; do case $m in https://* | tor+https://* | mirror+https://* | file:* | cdrom:* | copy:*) continue ;; esac for a in ${CB_HTTP_ALLOWED_URIS:-}; do case $m in "$a"*) continue 2 ;; esac done echo "$src: $m" done done done) n=$(printf '%s\n' "$entries" | grep -c .) if [ -n "$bad" ]; then printf '%s\n' "$bad" exit 1 fi echo "$n entries, all over https or a local method" remediation: manual: | 1. Install `ca-certificates`. 2. In each source entry, and in the mirror lists named after `mirror+file:`, replace `http://` with `https://` when the mirror serves HTTPS (`deb.debian.org` and `security.debian.org` do). Pick another mirror otherwise. 3. Run `apt-get update` and check that it prints no error. effects: restart: none disruption: low lockout_risk: false rollback: | Restore the source files from the backup directory printed by `remediate.sh`, or replace `https://` with `http://` again. scripts: - id: https-debian engine: shell file: fix.sh references: - title: sources.list(5), Debian manual pages url: https://manpages.debian.org/trixie/apt/sources.list.5.en.html publisher: Debian kind: vendor-doc accessed: 2026-10-18 - title: apt-transport-https(1), Debian manual pages url: https://manpages.debian.org/trixie/apt/apt-transport-https.1.en.html publisher: Debian kind: vendor-doc accessed: 2026-10-18 - title: Debian - deb.debian.org url: https://deb.debian.org/ publisher: Debian kind: vendor-doc accessed: 2026-10-18 mappings: - framework: nist-800-53r5 framework_version: "5.1.1" id: SC-8 relation: related - framework: cis-debian-13 framework_version: "1.1.0" id: "1.2.1.10" relation: equivalent - framework: cis-debian-13 framework_version: "1.1.0" id: "1.2.1.11" relation: equivalent threats: - framework: mitre-attack id: T1557 - framework: cwe id: CWE-319 related_controls: - id: CB-DEB-PKG-001 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 stock cloud images (https mirror lists); http entries in sources.list, .sources and mirror+file lists detected; fix switches deb/security.debian.org to https, apt-get update works without warning; http_allowed_uris honoured by check and fix; kept after reboot." - 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 stock cloud images (https mirror lists); http entries in sources.list, .sources and mirror+file lists detected; fix switches deb/security.debian.org to https, apt-get update works without warning; http_allowed_uris honoured by check and fix; kept after reboot." introduced_in: 0.1.0 created: 2026-10-18 updated: 2026-10-18