Subject: (on-topic) Re: bug#19479: Package manager vulnerable

From: Kelly Dean <[email-masked]>
Date: Sun, 11 Jan 2015 02:56:22 +0000

Back on topic...

I found a good way to add timestamps to prevent metadata replay (the other vulnerability), and to further harden the package manager's security, but of course I'll wait until we hear from the clerk before trying to implement it.

The reason I said there's a compatibility problem for timestamps is that archive-contents is a list consisting just of a version number followed by a bunch of package records; the list's format isn't extensible (though the package record format is extensible). There's no way to insert a timestamp without changing the list's format (and thus, the version number), but if you do that, then old clients can't understand archive-contents anymore.

Even worse, old clients become stuck because they store the new-format (incompatible) file before checking the version number, then barf on it and refuse to accept even an old-format (compatible) file to replace it until you manually delete the stored one.

I see four possible solutions:
0. Have a flag day, on which all the elpas switch to the new format, and on or before which everybody must upgrade to Emacs 25 or his package manager will stop working.
1. Have the server check the User-Agent header, and send the old-format file if it's ⌜URL/Emacs⌝, and the new-format if it's ⌜URL/Emacs-25⌝ or later.
2. Use a different URL for the new-format file.
3. Keep the old format, and put the timestamp in a different file.

#0 obviously isn't an option.
I advise against #1, for reasons which everybody here already knows.
#2 would work, but is inelegant, since you would still have to retain the old-format file for the sake of old clients, and it's inefficient, since new clients would have to periodically re-download the entire file (fairly big, in Melpa's case) even if nothing but the timestamp changed (and clients have to demand fresh timestamps in order to prevent metadata replay attacks).

#3 looks like the best solution. The timestamp file includes the timestamp and the hash of archive-contents. Sign the timestamp file for the sake of new clients.

Old clients would ignore the timestamp file. If archive-contents is unchanged, then new clients would only have to periodically re-download the timestamp file and signature--the minimal amount of data necessary. They'd see that the current hash of archive-contents matches the version they already have stored. IOW, to whoever made archive-contents inextensible: thank you! You've forced the right solution to timestamping. ;-)

Combined with my previous patch, this leaves the timestamp-file's signature as the only one that's necessary to secure the entire archive (packages and metadata, including timestamp) and prevent both package and metadata replay attacks. IMHO, this simplicity makes it practical to insist that all elpas provide this signature, so Emacs 25 could enforce it by default.

Optionally continue signing archive-contents for the sake of 24.4 clients, but since 25 won't need that signature, nothing before 24.4 is capable of checking it, 24.4 doesn't enforce it by default, Melpa doesn't even provide it IIUC (GNU Elpa does), and 24.4 is vulnerable to package and metadata replay anyway, you might as well not. The kind of people who have changed package-check-signature to t will upgrade to 25 anyway.