Subject: bug#19479: Package manager vulnerable to replay attacks

From: Stefan Kangas <[email-masked]>
Date: Wed, 25 Nov 2020 21:06:38 -0500

Stefan Monnier <[email-masked]> writes:

> Do we need this hash-checksum, really?

AFAIK, a cryptographic hash is the generally accepted solution for
securely verifying the contents of a file.  That is, when you worry
about that file having been tampered with by a hostile actor.

> AFAICT, I think if we want to avoid replay attacks we need indeed
> a monotone "counter" (e.g. a timestamp) on the `archive-contents` and
> then a way to verify that the tarballs are what they claim to be.

We also need to sign `archive-contents', of course.  But otherwise
correct: we need to know that the metadata is not out-of-date, and we
need to have a (secure) mapping from the package metadata to individual
packages.

> We can already verify that they are what they claim to be since the
> tarball includes the version number inside the `<pkg>-pkg.el` file.
>
> So, I think all we need is to verify the contents of `<pkg>-pkg.el`
> after unpacking a tarball, to make sure it is indeed the package and
> version its name claimed to be.  This check would be welcome in any case
> to detect packaging errors.

I think the question here is: how do we securely map from the (signed)
package metadata to an individual package?

While not perfect, with a secure hash function, collisions are hard
enough to find that we for our purposes (like the rest of the world) can
happily not worry about it.  In comparison, it is immeasurably easier to
fake a version number than having to defeat a hash function.  I think
this is a significant drawback of what you propose.

We would need to add in a number of assumptions (e.g. packages are
individually signed, we never accidentally sign an old package with a
newer version number, etc.), to gain more confidence in a simple version
number check.

But even then the security it provides will not be as strong, and much
more brittle; there are just more moving parts where things could go
wrong.  And I'm not sure what we would gain.  Importantly, I don't think
it would simplify our implementation in Emacs (or GNU/NonGNU ELPA)
significantly.

But we could of course also check that the version number is correct.
That sounds like a useful sanity check to do.

Thanks for taking a look at this!

PS. Note that if we add a checksum, there will no longer be any need to
    sign individual packages for future versions of Emacs.  We would
    then only need to sign the metadata.