CVE-2026-109518: APT flaw lets a hostile mirror install packages as root
Debian, Ubuntu and the APT developers published coordinated advisories on November 4, 2026 for CVE-2026-109518, a flaw in APT's HTTP download code that lets an attacker on the network path get a package installed after it has failed signature verification. Package maintainer scripts run as root, so a successful attack gives the attacker root on the machine. Max Justicz found and reported the bug. Ubuntu rates it High with a CVSS 4.0 score of 7.7; the APT developers describe it as a "critical file verification bypass." None of the three advisories reports exploitation in the wild, and the fixes are already in the archives.
How the package swap works
APT's archive signatures normally catch a tampered package: the Release file is signed, it lists hashes for every package, and a package that does not match is rejected. This bug sits underneath that check. An attacker who can modify HTTP traffic between the server and the archive answers download requests with a mix of redirects and temporary server errors. Those errors make APT retry the download, and during the retry APT reuses hard links in a way that lets the attacker's file overwrite the one that already passed verification. The swapped file is what gets installed.
Three conditions have to hold:
- The package source is reached over plain HTTP. Ubuntu states that HTTPS sources are protected, and FTP and other transports are not affected.
- The attacker controls the path or the server: a hostile mirror, a compromised or malicious proxy, or someone positioned on the network between you and the mirror.
- APT is configured to retry failed downloads (
Acquire::Retriesgreater than zero) and a package install or upgrade is triggered.
The flaw lives in the APT library, so every front end is affected: apt, apt-get, aptitude, unattended-upgrades and Ubuntu's graphical updaters. Snap packages are not affected.
Releases exposed by default
APT has defaulted Acquire::Retries to 3 since Debian 12 (bookworm) and Ubuntu 22.04 LTS. Those releases and everything newer are vulnerable out of the box: Debian 12 and 13, and Ubuntu 22.04, 24.04, 26.04 and 26.10. Debian 11 and Ubuntu 20.04 and older default to zero retries and are only exposed if someone set the option, which is common in provisioning scripts and CI images written to survive flaky mirrors.
Fixed APT versions
- Ubuntu 26.10: 3.3.3ubuntu0.1
- Ubuntu 26.04 LTS: 3.2.1ubuntu0.1
- Ubuntu 24.04 LTS: 2.8.4ubuntu0.1
- Ubuntu 22.04 LTS: 2.4.15ubuntu0.1
- Ubuntu 20.04 and 18.04 LTS: 2.0.12+esm1 and 1.6.19+esm1, through Ubuntu Pro ESM
- Ubuntu 16.04 and 14.04 LTS: 1.2.36+esm1 and 1.0.1ubuntu2.24+esm4, Ubuntu Pro with the Legacy add-on
- Debian 13 trixie: 3.0.4 (DSA-6607-1)
- Debian 12 bookworm: 2.6.2 (DLA-4880-1)
- Debian unstable: 3.3.6. Testing (forky) was still on 3.3.5 when the advisories went out.
Ubuntu's notice is USN-8996-1. Upstream also tagged fixes on the older stable branches (2.2.x for Debian 11 among them) for anyone building APT from source.
Checking and patching a server
Check the installed version and the effective retry setting:
apt list --installed '?source-package(^apt$)'
apt-config dump Acquire::Retries
Then update with retries switched off for that one run. Downloading the fixed APT uses the vulnerable APT, so this closes the window during the patch itself. Canonical gives these forms:
# Full upgrade
sudo apt update && sudo apt upgrade -o Acquire::Retries=0
# APT only
sudo apt update && sudo apt install -o Acquire::Retries=0 --only-upgrade '?source-package(^apt$)'
On Debian, apt-get install --only-upgrade -o Acquire::Retries=0 apt does the same job. Run the version check again afterwards and compare it against the list above.
unattended-upgrades will pull the fix within its normal 24-hour cycle on systems where it is enabled, but it will do so with the default retry setting. On a server you trust to be on a clean network that is acceptable. On anything behind a proxy you do not control, patch by hand.
Neither vendor offers a workaround beyond setting retries to zero. If a machine cannot be patched today, add a temporary drop-in and remove it once APT is current:
echo 'Acquire::Retries "0";' | sudo tee /etc/apt/apt.conf.d/99-cve-2026-109518
Moving package sources to HTTPS
HTTPS takes the on-path attacker out of this attack. Find what your sources use:
grep -rhE '^(deb |URIs:)' /etc/apt/sources.list /etc/apt/sources.list.d/ 2>/dev/null
On Ubuntu 24.04 and later the sources live in /etc/apt/sources.list.d/ubuntu.sources; on Debian 13 they are usually in /etc/apt/sources.list.d/debian.sources or the classic /etc/apt/sources.list. Change http:// to https:// on the archive and security lines, then run sudo apt update and confirm there are no errors. deb.debian.org, archive.ubuntu.com and security.ubuntu.com all serve HTTPS. Some country and community mirrors do not, which shows up as a failed fetch during the update. APT has had HTTPS support built in since 1.5, so no extra transport package is needed on any supported release.
HTTPS does not help against a malicious mirror that serves the attack itself over TLS. Only the patched APT closes that case.
Containers, build servers and Proxmox hosts
Docker images built from debian:bookworm, debian:trixie, ubuntu:22.04 or newer carry whatever APT version was current when the base image was pulled, and they run apt-get install during every build. Pull fresh base images and rebuild, or set Acquire::Retries=0 in the Dockerfile until the base images on your registry are current. Build runners on shared CI networks or behind caching proxies such as apt-cacher-ng are the most realistic place for an on-path attacker to sit.
Proxmox VE 8 runs on Debian 12 and Proxmox VE 9 on Debian 13, so both pick up the Debian fix through their normal Debian repositories. Patch the hypervisor before the guests; a root compromise there reaches every VM on the node.