Bug#749795: apt: no authentication checks for source packages
On Thu, May 29, 2014 at 11:04:35PM +0200, Jakub Wilk wrote:
> Package: apt
> Version: 1.0.3
> Severity: grave
> Tags: security
Thanks for your bugreport. You raise a important issue, but I agree
with David that its best if this goes through the security team for
coordination.
> I've been investigating how apt behaves when the repository doesn't
> contain any Release signatures (possibly because they were stripped
> off by a man-in-the-middle attacker).
>
> This is what I found out:
>
> | # cat /etc/apt/sources.list
> | deb http://ftp.debian.org/debian/ unstable main
> | deb-src http://ftp.debian.org/debian/ unstable main
> |
> | # apt-get update
> | Ign http://ftp.debian.org unstable InRelease
> | Ign http://ftp.debian.org unstable Release.gpg
> | Get:1 http://ftp.debian.org unstable Release [205 kB]
> | Get:2 http://ftp.debian.org unstable/main Sources [7249 kB]
> | Get:3 http://ftp.debian.org unstable/main amd64 Packages [6758 kB]
> | Fetched 14.2 MB in 29s (479 kB/s)
> | Reading package lists... Done
> |
> | # echo $?
> | 0
>
> Hmm. There is no warning suggesting that anything fishy is going on,
> and the exit code indicates success. (Perhaps the "Ign"s could raise
> suspicion of an observant sysadmin. But who knows what "Ign" exactly
> means? At least the apt-get(1) manpage doesn't know.)
Right, I think apt should show a more prominent warning here. I will
look into this next.
[..]
> So far, so good. However, apt-get happily downloads unauthenticated
> source packages, with no warning:
>
> | $ apt-get source -d nyancat
> | Reading package lists... Done
> | Building dependency tree
> | Reading state information... Done
> | Selected version '1.2.2-1' (unstable) for nyancat
> | Need to get 20.6 kB of source archives.
> | Get:1 http://ftp.debian.org/debian/ unstable/main nyancat 1.2.2-1 (dsc) [1782 B]
> | Get:2 http://ftp.debian.org/debian/ unstable/main nyancat 1.2.2-1 (tar) [14.1 kB]
> | Get:3 http://ftp.debian.org/debian/ unstable/main nyancat 1.2.2-1 (diff) [4748 B]
> | Fetched 20.6 kB in 0s (1838 kB/s)
> | Download complete and in download only mode
[..]
Indeed, this is a problem that needs fixing. Attached is a patch that
addresses the issue.
Cheers,
Michael
>From b7f501b5cc8583f61467f0c7a0282acbb88e4b29 Mon Sep 17 00:00:00 2001
From: Michael Vogt <mvo@debian.org>
Date: Fri, 30 May 2014 14:47:56 +0200
Subject: [PATCH] Show unauthenticated warning for source packages as well
This will show the same unauthenticated warning for source packages
as for binary packages and will not download a source package if
it is unauthenticated. This can be overriden with
--allow-unauthenticated
Closes: #749795
---
apt-private/private-download.cc | 5 +++++
apt-private/private-download.h | 6 +++++
cmdline/apt-get.cc | 9 ++++++++
test/integration/test-apt-get-source-authenticated | 26 ++++++++++++++++++++++
4 files changed, 46 insertions(+)
create mode 100755 test/integration/test-apt-get-source-authenticated
diff --git a/apt-private/private-download.cc b/apt-private/private-download.cc
index a095f0c..be7d23c 100644
--- a/apt-private/private-download.cc
+++ b/apt-private/private-download.cc
@@ -28,6 +28,11 @@ bool CheckAuth(pkgAcquire& Fetcher, bool const PromptUser)
if (UntrustedList == "")
return true;
+ return AuthPrompt(UntrustedList, PromptUser);
+}
+
+bool AuthPrompt(std::string UntrustedList, bool const PromptUser)
+{
ShowList(c2out,_("WARNING: The following packages cannot be authenticated!"),UntrustedList,"");
if (_config->FindB("APT::Get::AllowUnauthenticated",false) == true)
diff --git a/apt-private/private-download.h b/apt-private/private-download.h
index a108aa5..a90ac7e 100644
--- a/apt-private/private-download.h
+++ b/apt-private/private-download.h
@@ -5,7 +5,13 @@
class pkgAcquire;
+// Check if all files in the fetcher are authenticated
APT_PUBLIC bool CheckAuth(pkgAcquire& Fetcher, bool const PromptUser);
+
+// show a authentication warning prompt and return true if the system
+// should continue
+APT_PUBLIC bool AuthPrompt(std::string UntrustedList, bool const PromptUser);
+
APT_PUBLIC bool AcquireRun(pkgAcquire &Fetcher, int const PulseInterval, bool * const Failure, bool * const TransientNetworkFailure);
#endif
diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc
index 0f18b0e..d74d6d5 100644
--- a/cmdline/apt-get.cc
+++ b/cmdline/apt-get.cc
@@ -76,6 +76,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/statfs.h>
#include <sys/statvfs.h>
@@ -755,6 +756,7 @@ static bool DoSource(CommandLine &CmdL)
// Load the requestd sources into the fetcher
unsigned J = 0;
+ std::string UntrustedList;
for (const char **I = CmdL.FileList + 1; *I != 0; I++, J++)
{
string Src;
@@ -763,6 +765,9 @@ static bool DoSource(CommandLine &CmdL)
if (Last == 0) {
return _error->Error(_("Unable to find a source package for %s"),Src.c_str());
}
+
+ if (Last->Index().IsTrusted() == false)
+ UntrustedList += Src + " ";
string srec = Last->AsStr();
string::size_type pos = srec.find("\nVcs-");
@@ -846,6 +851,10 @@ static bool DoSource(CommandLine &CmdL)
Last->Index().SourceInfo(*Last,*I),Src);
}
}
+
+ // check authentication status of the source as well
+ if (UntrustedList != "" && !AuthPrompt(UntrustedList, true))
+ return false;
// Display statistics
unsigned long long FetchBytes = Fetcher.FetchNeeded();
diff --git a/test/integration/test-apt-get-source-authenticated b/test/integration/test-apt-get-source-authenticated
new file mode 100755
index 0000000..e384b3d
--- /dev/null
+++ b/test/integration/test-apt-get-source-authenticated
@@ -0,0 +1,26 @@
+#!/bin/sh
+set -e
+
+TESTDIR=$(readlink -f $(dirname $0))
+. $TESTDIR/framework
+
+setupenvironment
+configarchitecture "i386"
+
+# a "normal" package with source and binary
+buildsimplenativepackage 'foo' 'all' '2.0'
+
+setupaptarchive --no-update
+
+APTARCHIVE=$(readlink -f ./aptarchive)
+rm -f $APTARCHIVE/dists/unstable/*Release*
+
+# update without authenticated InRelease file
+testsuccess aptget update
+
+# this all should fail
+testfailure aptget install -y foo
+testfailure aptget source -y foo
+
+# allow overriding the warning
+testsuccess aptget source --allow-unauthenticated foo
--
1.9.1
Reply to: