all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Kelly Dean <kelly@prtime.org>
To: Stefan Monnier <monnier@iro.umontreal.ca>
Cc: 19479@debbugs.gnu.org
Subject: bug#19479: [PATCH] Re: bug#19479: Package manager vulnerable
Date: Thu, 08 Jan 2015 03:31:01 +0000	[thread overview]
Message-ID: <iHwGTo6KPGu52f1tOLq6Ek7KcZ7r2tufrT1z4GnPndF@local> (raw)
In-Reply-To: <jwvsifq7zbm.fsf-monnier+emacsbugs@gnu.org>

[-- Attachment #1: Type: text/plain, Size: 2116 bytes --]

Stefan Monnier wrote:
> > If filenames include version numbers and the version numbers are never
> > reused,
>
> The ELPA system in general does not enforce that.  But the GNU ELPA
> scripts do, and other ELPA servers work in a way that should generally
> make sure this is also the case.

But having security rely on that makes it easier than necessary to accidentally open a window of vulnerability by failing to enforce that constraint. It's a brittle solution.

>> then your solution does prevent package replay attacks. Since Emacs
>> packages already include a Version header (and the package name), you could
>> actually do your proposed verification using that header, without changing
>> the way signatures are currently made, which is a solution I addressed in my
>> original emacs-devel message.
>
> Indeed, I realized this just after I sent my message.
> So we can fix this problem simply by changing package.el so as to check
> that the name&version of the downloaded file match the name&version
> contained therein.
> Patch welcome.

Ok, but as I explained in my original message, that solution still makes the attacker's job easier than necessary in some cases. Verifying the hash is a more robust solution than verifying the version number, so my patch below verifies the hash.

This is forward compatible. You can install this now and start putting archive-contents with hashes on elpa (and melpa and marmalade), and old clients will simply ignore the hashes and operate as usual.

BTW, one happy side effect of properly fixing this vulnerability is eliminating melpa's incentive to mangle package version numbers (they're mangled apparently to deal with the problem of package maintainers reusing version numbers).

> It should be fairly easy to add a timestamp in there without
> causing any backward incompatibility.

Unfortunately, I don't see how to add timestamps to archive-contents without breaking old clients, so the metadata replay vulnerability will have to remain open until you decide how to handle the compatibility problem. My patch here only fixes the package replay vulnerability.

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: package-replay-vuln.patch --]
[-- Type: text/x-diff, Size: 3425 bytes --]

--- emacs-24.4/lisp/emacs-lisp/package.el
+++ emacs-24.4/lisp/emacs-lisp/package.el
@@ -314,6 +314,11 @@
 
 (defvar package--default-summary "No description available.")
 
+(defvar package-hashfun 'sha256 "Function for secure hashing.")
+
+(defvar package-acceptable-hashfuns '(sha256)
+  "Past and current `package-hashfun' functions that are still secure.")
+
 (cl-defstruct (package-desc
                ;; Rename the default constructor from `make-package-desc'.
                (:constructor package-desc-create)
@@ -843,6 +848,20 @@
                          (epg-context-result-for context 'verify)))
         good-signatures))))
 
+(defun package--check-size (pkg-desc)
+  (eq (cdr (assoc :size (package-desc-extras pkg-desc)))
+      (pcase (package-desc-kind pkg-desc)
+	(`single (string-bytes (buffer-string)))
+	(`tar (buffer-size)) ; Because insert-file-contents mangled the literal
+	(kind (error "Unknown package kind: %s" kind)))))
+
+(defun package--check-hash (pkg-desc)
+  (let* ((x (cdr (assoc :hash (package-desc-extras pkg-desc))))
+	 (hashfun (car x)) ; Avoid Git's shortsightedness
+	 (hash (cadr x)))
+    (and (memq hashfun package-acceptable-hashfuns)
+	 (string= hash (secure-hash hashfun (current-buffer))))))
+
 (defun package-install-from-archive (pkg-desc)
   "Download and install a tar package."
   (let* ((location (package-archive-base pkg-desc))
@@ -859,6 +878,10 @@
 	    (unless (eq package-check-signature 'allow-unsigned)
 	      (error "Unsigned package: `%s'"
 		     (package-desc-name pkg-desc)))))
+      (unless (package--check-size pkg-desc)
+	(error "File size not correct: %s" (package-desc-name pkg-desc)))
+      (unless (package--check-hash pkg-desc)
+	(error "Failed to verify hash: %s" (package-desc-name pkg-desc)))
       (package-unpack pkg-desc))
     ;; Here the package has been installed successfully, mark it as
     ;; signed if appropriate.
@@ -1172,7 +1195,10 @@
            (package--prepare-dependencies
             (package-read-from-string requires-str)))
        :kind 'single
-       :url homepage))))
+       :url homepage
+       :size (string-bytes (buffer-string))
+       :hash (list package-hashfun
+		   (secure-hash package-hashfun (current-buffer)))))))
 
 (declare-function tar-get-file-descriptor "tar-mode" (file))
 (declare-function tar--extract "tar-mode" (descriptor))
@@ -1184,7 +1210,10 @@
   (let* ((dir-name (file-name-directory
                     (tar-header-name (car tar-parse-info))))
          (desc-file (package--description-file dir-name))
-         (tar-desc (tar-get-file-descriptor (concat dir-name desc-file))))
+         (tar-desc (tar-get-file-descriptor (concat dir-name desc-file)))
+	 (size (buffer-size tar-data-buffer))
+	 (hash (list package-hashfun
+		     (secure-hash package-hashfun tar-data-buffer))))
     (unless tar-desc
       (error "No package descriptor file found"))
     (with-current-buffer (tar--extract tar-desc)
@@ -1196,7 +1225,8 @@
                       (error "Can't find define-package in %s"
                              (tar-header-name tar-desc))
                     (apply #'package-desc-from-define
-                           (append (cdr pkg-def-parsed))))))
+                           (append (cdr pkg-def-parsed)
+				   (list :size size :hash hash))))))
             (setf (package-desc-kind pkg-desc) 'tar)
             pkg-desc)
         (kill-buffer (current-buffer))))))

  reply	other threads:[~2015-01-08  3:31 UTC|newest]

Thread overview: 65+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-12-30 10:42 Emacs package manager vulnerable to replay attacks Kelly Dean
2014-12-30 11:45 ` Ivan Shmakov
2015-01-01 12:38 ` bug#19479: Package manager vulnerable Kelly Dean
2015-01-04 20:00   ` Stefan Monnier
2015-01-05  1:11     ` Kelly Dean
2015-01-05  2:16       ` Stefan Monnier
2015-01-08  3:31         ` Kelly Dean [this message]
2015-01-08  3:44           ` bug#19479: [PATCH] " Glenn Morris
2015-01-08  5:29             ` Kelly Dean
2015-01-08 14:39               ` Stefan Monnier
2015-01-08 21:06                 ` Kelly Dean
2015-01-09  2:37                   ` Stefan Monnier
2015-01-09  6:59               ` bug#19479: Copyright issue (was: Re: bug#19479: Package manager vulnerable) Kelly Dean
2015-01-09 15:17                 ` bug#19479: Copyright issue Stefan Monnier
2015-01-09 15:29                   ` David Kastrup
2015-01-09 21:00                     ` Kelly Dean
2015-01-09 21:49                       ` Kelly Dean
2015-01-09 23:47                         ` Stefan Monnier
2015-01-10  1:18                           ` Kelly Dean
2015-01-11  1:39                             ` Stefan Monnier
2015-01-11  3:20                               ` Kelly Dean
2015-01-11  6:33                                 ` Werner LEMBERG
2015-01-12 15:38                               ` Richard Stallman
2015-01-10 19:29                         ` Richard Stallman
2015-01-09 15:29                   ` David Kastrup
2015-01-09 19:57                   ` Kelly Dean
2015-01-09 19:57                   ` Kelly Dean
2015-01-09 20:24                     ` bug#19479: " Glenn Morris
2015-01-09 20:24                     ` Glenn Morris
2015-01-09 20:32                       ` Glenn Morris
2015-01-09 20:32                       ` Glenn Morris
2015-02-24  8:47           ` Emacs package manager vulnerable to replay attacks Kelly Dean
2015-02-24  8:47           ` bug#19479: " Kelly Dean
2015-01-11  2:56   ` bug#19479: (on-topic) Re: bug#19479: Package manager vulnerable Kelly Dean
2015-01-20 21:18   ` bug#19479: Disclaimer is now on file at FSF Kelly Dean
2015-02-24 18:11     ` Glenn Morris
2015-02-24 18:11     ` Glenn Morris
2015-02-24 23:02       ` Kelly Dean
2015-02-24 23:02       ` Kelly Dean
2015-02-25 21:09         ` Glenn Morris
2017-09-02 12:24           ` Eli Zaretskii
2015-02-25 21:09         ` Glenn Morris
2015-02-25  4:41       ` Vibhav Pant
2015-02-25  5:32         ` Stephen J. Turnbull
2017-09-03  1:10   ` bug#19479: Package manager vulnerable Glenn Morris
2019-10-04  9:49   ` Stefan Kangas
2020-05-06  0:55     ` Noam Postavsky
2020-09-06 23:59       ` Stefan Kangas
2020-09-07 14:14         ` Noam Postavsky
2020-09-07 18:11           ` Stefan Kangas
2020-11-21 23:51     ` bug#19479: Package manager vulnerable to replay attacks Stefan Kangas
2020-11-26  0:43       ` Stefan Monnier
2020-11-26  2:06         ` Stefan Kangas
2020-11-26  2:30           ` Stefan Monnier
2020-11-26  3:02             ` Stefan Kangas
2020-11-26  3:11               ` Stefan Monnier
2020-11-26  3:56           ` Jean Louis
2020-09-07 17:19   ` bug#19479: Package manager vulnerable Stefan Kangas
2020-09-07 23:54     ` Noam Postavsky
2020-09-08  8:10       ` Stefan Kangas
  -- strict thread matches above, loose matches on Subject: below --
2015-01-08  3:33 bug#19536: [PATCH] package-upload-buffer-internal fails for tar files Kelly Dean
2015-01-08  5:50 ` Stefan Monnier
2015-01-08  7:10   ` Kelly Dean
2015-01-08 11:40   ` bug#19479: Package manager vulnerable Kelly Dean
2015-02-18  1:03 ` bug#19536: package-upload-buffer-internal fails for tar files Kelly Dean

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=iHwGTo6KPGu52f1tOLq6Ek7KcZ7r2tufrT1z4GnPndF@local \
    --to=kelly@prtime.org \
    --cc=19479@debbugs.gnu.org \
    --cc=monnier@iro.umontreal.ca \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.