Public bug reported:

Package: apt 3.2.0, Ubuntu 26.04.1 LTS (resolute), amd64

- installed: apt 3.2.0 and libapt-pkg7.0 3.2.0 (amd64, Ubuntu 26.04.1 LTS), 
source package apt 3.2.0
- dsc file: apt_3.2.0.dsc SHA256 
364347278a531cf073f809a14f84617c2b935cfb324bd413aa01c214b6f8a3e8, signature 
verified with gpgv, key 4FB588A84C2DDE79A74C77876FA458DD1DB03F71
- source file: apt_3.2.0.tar.xz SHA256 
dcd186912a7b8553cc885412127925858ee340c655e2f26e77eacdab23f48089, matches 
Checksums-Sha256 in the signed .dsc
- container for the test: ubuntu:26.04, image 
ubuntu@sha256:c098726dd9b9733f3e885f8de0ef375206a311b0a317eadc40d347b1115fb944 
(created 2026-10-06)

Description:

Severity: low (hardening).

sources.list(5) describes Check-Valid-Until as follows: "A repository
creator can declare a time until which the data provided in the
repository should be considered valid, and if this time is reached, but
no new data is provided, the data is considered expired and an error is
raised. Besides increasing security, as a malicious attacker can't send
old data forever to prevent a user from upgrading to a new version, this
also helps users identify mirrors which are no longer updated."
apt.conf(5) calls it a security-related option that defaults to true and
"prevents replay attacks over a long timescale".

In 3.2.0 the check runs only when a Release file is fetched:
pkgAcqMetaBase::VerifyVendor compares ValidUntil with the clock (apt-
pkg/acquire-item.cc:1831-1868). Nothing else compares it with the clock.
The only other use of the value is the Signed-By carry-over in apt-
pkg/deb/debmetaindex.cc (around line 1470), which decides whether to
reuse the previous Release's Signed-By. Commands that work from the
stored lists (install, upgrade, policy and so on) never check whether
the stored Release has expired.

An expired repository makes apt update fail, but a later apt-get install
still installs from the stored index and prints nothing. The protection
the man page describes only works if apt update is run and its failure
stops whatever comes next. A host that stops updating, or a script that
ignores the failure, keeps using the expired data.

Test (container, run as root; apt-ftparchive does not write a Valid-
Until field, so the script adds it by hand, 60 seconds from now):

    apt-get update >/dev/null 2>&1; apt-get install -y -q apt-utils >/dev/null 
2>&1
    mkdir -p /repo /pkg/DEBIAN
    printf 'Package: testpkg\nVersion: 1.0\nArchitecture: all\nMaintainer: t 
<[email protected]>\nDescription: test\n' > /pkg/DEBIAN/control
    dpkg-deb --build /pkg /repo/testpkg_1.0_all.deb >/dev/null
    cd /repo && apt-ftparchive packages . > Packages && apt-ftparchive release 
. > Release
    sed -i "1i Valid-Until: $(date -u -d '+60 seconds' '+%a, %d %b %Y %H:%M:%S 
UTC')" Release
    rm -f /etc/apt/sources.list.d/*.sources /etc/apt/sources.list
    echo 'deb [trusted=yes] file:/repo ./' > /etc/apt/sources.list.d/t.list
    apt-get update
    sleep 70
    apt-get update
    apt-get install -y testpkg

Output (progress lines removed):

    == 23:57:40 apt-get update (not yet expired)
    Get:2 file:/repo ./ Release [859 B]
    Get:4 file:/repo ./ Packages [437 B]
    rc=0
    == 23:58:50 apt-get update (expired)
    Get:2 file:/repo ./ Release [859 B]
    E: Release file for file:/repo/./Release is expired (invalid since 10s). 
Updates for this repository will not be applied.
    rc=100
    == apt-get install testpkg (no update in between)
    The following NEW packages will be installed:
      testpkg
    Get:1 file:/repo ./ testpkg 1.0 [454 B]
    Unpacking testpkg (1.0) ...
    Setting up testpkg (1.0) ...
    rc=0
    ii  testpkg        1.0          all          test

Not tested: a signed repository served over http (the test used an
unsigned file: source with [trusted=yes]). The code path that checks the
value is the same for any source, and no use-time check exists in the
code I read.

Expected:
- Commands that use the stored lists check the Valid-Until of each stored 
Release against the clock, in the same way as apt update, and report an expired 
repository as an error (or at least a warning), unless Check-Valid-Until is 
disabled for that source.
- Or, if the check is meant to apply only to apt update, say so in 
sources.list(5) and apt.conf(5), since the text now reads as if an expired 
repository raises an error in general.

** Affects: apt (Ubuntu)
     Importance: Undecided
         Status: New

-- 
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/2172193

Title:
  apt: an expired Valid-Until is refused by apt update but ignored by
  apt-get install, which installs from the expired index without a
  message

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/apt/+bug/2172193/+subscriptions


-- 
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs

Reply via email to