Skip to content
Exploit for CVE-2026

Exploit for CVE-2026

Sploitus • November 4, 2026

![Class](

![CVSS](

![Disclosed](

![Shell](

![License](

![Version](

Read-only audit script for **CVE-2026-109518**, a flaw in the HTTP backend of **APT** (Debian, Ubuntu and derivatives). An attacker who can alter the HTTP traffic between a client and its archive server can get an unverified, attacker-controlled `.deb` installed, and package scripts run as root.

APT can merge two different downloads when a redirect gives them the same address (it reuses a hard link, CWE-62). If a download is retried, the data of a second, attacker-influenced transfer can end up in the file that already passed signature verification. Maintainer scripts then run as root.

| Component | APT, HTTP method (every APT frontend is affected: apt, apt-get, aptitude, unattended-upgrades) |

| Class | UNIX hard link reuse (CWE-62), verified package swapped after verification |

| Severity | CVSS 4.0: 7.7 High (`AV:N/AC:L/AT:P/PR:N/UI:P/VC:H/VI:H/VA:H`), Ubuntu priority High |

| Needs | On-path attacker on plain HTTP, redirects followed, and a **non-zero `Acquire::Retries`** |

| Not affected | Snaps, non-HTTP transports (FTP) |

| Ubuntu | USN-8996-1: 26.10 `3.3.3ubuntu0.1`, 26.04 `3.2.1ubuntu0.1`, 24.04 `2.8.4ubuntu0.1`, 22.04 `2.4.15ubuntu0.1`; ESM 20.04 `2.0.12+esm1`, 18.04 `1.6.19+esm1`; Legacy 16.04 `1.2.36+esm1`, 14.04 `1.0.1ubuntu2.24+esm4` |

| Debian | trixie `3.0.4` (DSA-6607-1), bookworm `2.6.2` (DLA-4880-1), sid `3.3.6`; bullseye not listed |

The default `Acquire::Retries` is 3 on Debian 12 / Ubuntu 22.04 and newer, which makes them affected out of the box. Older releases default to 0 and are only exposed when someone set a non-zero value. The default Ubuntu and Debian mirrors are plain HTTP, so most hosts meet all three conditions until patched.

Fix versions were taken from ubuntu.com/security/CVE-2026-109518, the Ubuntu blog post and security-tracker.debian.org on 2026-11-04. Vendors published no indicators of compromise, so this script does not hunt for any.

It only reports. It never installs, edits configuration or opens a network connection, and needs no root.

- Reads the installed `apt` version and the distro from `os-release`, and compares them with the vendor fix using a pure-bash port of the dpkg version rules.

- Reads the **effective `Acquire::Retries`**. `apt-config dump` hides built-in defaults, so an unset value is inferred (non-zero from apt 2.4).

- Lists the **enabled** sources by scheme through `apt-get indextargets` (so `Enabled: no` stanzas do not count), falling back to parsing `sources.list` and `*.sources`. `mirror+...` sources count as HTTP because the mirror list may point to HTTP mirrors.

- Notes when TLS verification is disabled (`Verify-Peer` / `Verify-Host` set to false): https sources then count as exposed too.

- Reads the local package lists to tell you whether the fix is already installable, and how old the lists are.

- Prints the exact commands to fix it. They are printed, not run.

| PATCHED | 0 | installed apt is at or above the fix |

| NOT_APPLICABLE | 0 | apt is not installed (RPM hosts, Solaris, Windows) |

| MITIGATED | 1 | apt is unfixed, but `Acquire::Retries` is 0 or no enabled source is open to a network attacker. Still patch |

| VULNERABLE | 2 | unfixed apt, retries enabled, at least one plain-HTTP source |

| UNKNOWN | 3 | no fix known for this release, or a derivative that may carry a backport |

./cve-2026-109518-audit.sh # text report

./cve-2026-109518-audit.sh --json # JSON

./cve-2026-109518-audit.sh --quiet # one line

Run the update **with retries off**, because `apt update` and `apt install` use the vulnerable path themselves:

sudo apt-get update -o Acquire::Retries=0

sudo apt-get install -o Acquire::Retries=0 --only-upgrade apt

Until then, `echo 'Acquire::Retries "0";' | sudo tee /etc/apt/apt.conf.d/99-cve-2026-109518` closes the retry path. Switching the archive URLs to ` also stops an on-path attacker, but some community mirrors do not offer HTTPS. No reboot is needed.

If the audit says the fix is not in your lists yet, run `apt-get update` first. If it still offers nothing, the vendor has not published the fix for your suite, or your mirror lags.

tools/fleet.sh web1 db1 pve1 pve2 # Linux, macOS, WSL, Git Bash

.\tools\fleet.ps1 web1 db1 pve1 pve2 # Windows PowerShell 5.1 / 7

The audit is streamed to `bash -s` over SSH, so nothing is left on the remote host. A pause between hosts (`-d` / `-DelaySeconds`, default 2 s) keeps shared hosts that rate-limit SSH logins from blocking you.

- **Ubuntu-based** (Mint, Pop!_OS, elementary): judged against the Ubuntu row for their `UBUNTU_CODENAME`.

- **Proxmox**: `ID=debian`, so the Debian rows apply.

- **Other Debian derivatives** (Kali, Devuan, ...): judged against upstream `3.3.6`. Below it the verdict is UNKNOWN, since a vendor backport has a lower version number that the script cannot recognise.

- **Containers**: the script audits the apt of the system it runs in. Docker images that run `apt-get` during a build carry their own apt and are not covered, so rebuild them after the base images are fixed.

- **Fix table freshness**: the table is a snapshot (2026-11-04). The report warns once it is 14 days old; pull the latest release of the script.

Each case runs the script against mocked `dpkg-query`, `apt-config`, `apt-get`, `apt-cache` and a fixture file tree. The version comparison is cross-checked against the real `dpkg` when it is available.

Extracted Entities