From c31d65e76810f72c356e381818174bf100605de7 Mon Sep 17 00:00:00 2001
From: Julian Andres Klode <julian.klode@canonical.com>
Date: Fri, 18 Jan 2019 09:13:52 +0100
Subject: SECURITY UPDATE: content injection in http method (CVE-2019-3462)

This fixes a security issue that can be exploited to inject arbritrary debs
or other files into a signed repository as followed:

(1) Server sends a redirect to somewhere%0a<headers for the apt method> (where %0a is
    \n encoded)
(2) apt method decodes the redirect (because the method encodes the URLs before
    sending them out), writting something like
    somewhere\n
    <headers>
    into its output
(3) apt then uses the headers injected for validation purposes.

Regression-Of: c34ea12ad509cb34c954ed574a301c3cbede55ec
LP: #1812353
(cherry picked from commit 5eb01ec13f3ede4bae5e60eb16bd8cffb7c03e1b)
---
 apt-pkg/acquire-method.cc                          |  6 ++
 .../test-cve-2019-3462-dequote-injection           | 66 ++++++++++++++++++++++
 2 files changed, 72 insertions(+)
 create mode 100755 test/integration/test-cve-2019-3462-dequote-injection

diff --git a/apt-pkg/acquire-method.cc b/apt-pkg/acquire-method.cc
index c9cd48bb6..c67c47ab8 100644
--- a/apt-pkg/acquire-method.cc
+++ b/apt-pkg/acquire-method.cc
@@ -470,6 +470,12 @@ void pkgAcqMethod::Status(const char *Format,...)
  * the worker will enqueue again later on to the right queue */
 void pkgAcqMethod::Redirect(const string &NewURI)
 {
+   if (NewURI.find_first_not_of(" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~") != std::string::npos)
+   {
+      _error->Error("SECURITY: URL redirect target contains control characters, rejecting.");
+      Fail();
+      return;
+   }
    std::unordered_map<std::string, std::string> fields;
    try_emplace(fields, "URI", Queue->Uri);
    try_emplace(fields, "New-URI", NewURI);
diff --git a/test/integration/test-cve-2019-3462-dequote-injection b/test/integration/test-cve-2019-3462-dequote-injection
new file mode 100755
index 000000000..a1adec6de
--- /dev/null
+++ b/test/integration/test-cve-2019-3462-dequote-injection
@@ -0,0 +1,66 @@
+#!/bin/sh
+set -e
+
+TESTDIR="$(readlink -f "$(dirname "$0")")"
+. "$TESTDIR/framework"
+setupenvironment
+configarchitecture 'amd64'
+
+# build two uncompressed packages
+buildsimplenativepackage 'alpha' 'all' '1' 'unstable' '' '' 'section' 'optional' '' 'none'
+
+setupaptarchive --no-update
+ORIGINAL_SHA256=$(sha256sum aptarchive/pool/alpha_1_all.deb | awk '{print $1}')
+ORIGINAL_SIZE=$(wc -c aptarchive/pool/alpha_1_all.deb | awk '{print $1}')
+SHA256="DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF"
+changetowebserver
+
+webserverconfig aptwebserver::redirect::replace::alpha_1_all.deb "beeta_1_all.deb%250a%250a201%2520URI%2520Done%250aURI:%2520http://localhost:${APTHTTPPORT}/pool/beeta_1_all.deb%250aFilename:%2520${TMPWORKINGDIRECTORY}/rootdir/var/cache/apt/archives/partial/alpha_1_all.deb%250aSize:%252020672%250aLast-Modified:%2520Fri,%252018%2520Jan%25202019%252009:52:02%2520+0000%250aSHA256-Hash:%2520${SHA256}%250aChecksum-FileSize-Hash:%252012345%250a%250a%0a"
+
+
+testsuccess apt update -o debug::http=1 -o debug::pkgacquire::worker=1
+
+
+testfailureequal "Reading package lists...
+Building dependency tree...
+The following NEW packages will be installed:
+  alpha
+0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
+Need to get 20.7 kB of archives.
+After this operation, 11.3 kB of additional disk space will be used.
+Err:1 http://localhost:${APTHTTPPORT} unstable/main all alpha all 1
+  SECURITY: URL redirect target contains control characters, rejecting.
+E: Failed to fetch http://localhost:${APTHTTPPORT}/pool/alpha_1_all.deb  SECURITY: URL redirect target contains control characters, rejecting.
+E: Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?" aptget install alpha
+
+
+
+# For reference, the following is the original reproducer/bug. It has
+# been disabled using exit 0, as it will fail in fixed versions.
+exit 0
+
+testfailureequal "Reading package lists...
+Building dependency tree...
+The following NEW packages will be installed:
+  alpha
+0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
+Need to get 20.7 kB of archives.
+After this operation, 11.3 kB of additional disk space will be used.
+Err:1 http://localhost:${APTHTTPPORT} unstable/main all alpha all 1
+  Hash Sum mismatch
+  Hashes of expected file:
+   - SHA256:$ORIGINAL_SHA256
+   - Filesize:$ORIGINAL_SIZE [weak]
+  Hashes of received file:
+   - SHA256:DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF
+   - Filesize:12345 [weak]
+  Last modification reported: Fri, 18 Jan 2019 09:52:02 +0000
+E: Failed to fetch http://localhost:${APTHTTPPORT}/pool/beeta_1_all.deb  Hash Sum mismatch
+   Hashes of expected file:
+    - SHA256:$ORIGINAL_SHA256
+    - Filesize:$ORIGINAL_SIZE [weak]
+   Hashes of received file:
+    - SHA256:DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF
+    - Filesize:12345 [weak]
+   Last modification reported: Fri, 18 Jan 2019 09:52:02 +0000
+E: Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?" aptget install alpha
-- 
cgit v1.2.3