[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Emacs package manager vulnerable to replay attacks
Emacs package manager vulnerable to replay attacks
Tue, 30 Dec 2014 10:42:16 +0000
Remove your ~/.emacs.d/elpa/ directory, and start 24.4.
Use the default of '(("gnu" . "http://elpa.gnu.org/packages/")) for
Do M-x list-packages, which will download the archive metadata
(http://elpa.gnu.org/packages/archive-contents and its sig file), verify the
sig, and generate archive-contents.signed which indicates successful
mkdir /tmp/localarch; cd /tmp/localarch
cp ~/.emacs.d/elpa/archives/gnu/* . # archive-contents and
wget http://elpa.gnu.org/packages/undo-tree-0.6.5.el # Currently latest in elpa
Now in Emacs, do (setq package-archives '(("gnu" . "/tmp/localarch/")))
Undo-tree 0.6.7 doesn't exist yet, but let's pretend that it does, and it fixes
a hypothetical security vulnerability in 0.6.5, and the update has been
uploaded to elpa. (Skipping 0.6.6 for this example since it does exist, just
not in elpa.)
To simulate this, edit /tmp/localarch/archive-contents, find the entry for
undo-tree, and change the (0 6 5) to (0 6 7). Your modified file will no longer
verify with http://elpa.gnu.org/packages/archive-contents.sig, but that's ok
since you already have /tmp/localarch/archive-contents.signed.
Now, to simulate a package replay attack, rename undo-tree-0.6.5.el to
undo-tree-0.6.7.el, and undo-tree-0.6.5.el.sig to undo-tree-0.6.7.el.sig. Then
do M-x list-packages again, then install undo-tree 0.6.7. It installs
successfully, meaning you've tricked Emacs into installing the vulnerable
version of the package even though archive-contents lists the fixed version.
For a live attack, first retrieve all packages and their sig files from elpa,
then wait for a vulnerability to be discovered and fixed in one of them, e.g.
Allow your victim to run list-packages to download the new archive-contents
(which lists the fixed undo-tree 0.6.7) and to verify it using the new
Then when he tries to download undo-tree-0.6.7.el and undo-tree-0.6.7.el.sig,
intercept his connection and give him the content of undo-tree-0.6.5.el and
undo-tree-0.6.5.el.sig, so that his Emacs saves the old content using the new
His Emacs will successfully verify the signature because it is authentic; you
retrieved authentic (but now stale) packages and signatures in your first step.
His Emacs will then install the stale package because the version number
embedded in the filename matches the version number specified in the new
The attack also works for already-installed packages when new versions are
published; you can deliver stale data when the victim tries to upgrade.
To solve the problem above, simply include a hash of the package content in the
package's record in archive-contents, rather than only including the package
name and version number in that file as Emacs currently does. This solution
also happens to make per-package signatures from the elpa key superfluous, so
you can remove that feature from Emacs and remove those signature files from
elpa for the sake of simplicity, and use the elpa key only to sign the
(Of course, per-commit (not just per-package) signatures from authors would
still be useful, so that users don't have to trust the elpa keyholder alone,
but that's a separate issue. Emacs should barf if a package hash doesn't
verify, regardless of whether any signatures verify.)
Package replay attacks could be prevented without putting hashes in
archive-contents, by instead verifying that the version number listed in
archive-contents matches the version number listed in the package itself, if
version numbers were never reused for different versions of packages. But there
is at least one package (undo-tree) that does re-use version numbers, so hashes
are still necessary. Hashes also prevent elpa itself from reusing version
numbers; forcing elpa to issue a new archive-contents whenever it lists a new
version of any package makes it more conspicuous that something changed, and
making the historical record clear closes off one particular method of attack
if the elpa key is compromised.
After the problem of package replay attacks is solved, you can still attack by
replaying not only packages, but also the metadata (i.e. the archive-contents
and archive-contents.sig files). To solve this problem, include a timestamp of
archive-contents in that file itself (so that the signature depends on the
timestamp), and have Emacs ignore any new archive-contents that's older than
the latest valid one that Emacs has already seen or is older than some
specified limit (IIRC Debian's apt-get uses a 10-day limit).
For details on replay attacks, see the 2008 publication
Another attack is the endless-data attack; I haven't checked whether Emacs is
But since Emacs signs its repository metadata, it appears it is not vulnerable
to any of the other attacks described on that page.
In addition to recording hashes, also record the length of the content; it's
convenient for early detection of endless-data attacks and of misconfigurations.
One final feature that isn't necessary for preventing any of the
vulnerabilities above, but still is helpful to make the historical record even
more clear, is to include in each version of archive-contents a hash (and
length) of the previous version of that file. This further constrains an
attacker who has compromised the elpa key; he can still launch attacks, but
it's harder to keep the attacks secret for very long, since he's forced to
cause a fork in what's supposed to be a linear hash chain.
Fortunately, all four of these features (package hashes, content length,
archive timestamps, and archive hash chaining) are straightforward to implement.
- Emacs package manager vulnerable to replay attacks,
Kelly Dean <=