Your message dated Tue, 29 Sep 2009 19:58:43 +0000
with message-id <e1msiqr-0004cp...@ries.debian.org>
and subject line Bug#547318: fixed in horde3 3.1.3-4etch6
has caused the Debian Bug report #547318,
regarding horde3: CVE-2009-3236 possibility to overwrite arbitrary files with
the permissions of the webserver
to be marked as done.
This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.
(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact ow...@bugs.debian.org
immediately.)
--
547318: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=547318
Debian Bug Tracking System
Contact ow...@bugs.debian.org with problems
--- Begin Message ---
Source: horde3
Severity: grave
Tags: security patch
Hi,
the following CVE (Common Vulnerabilities & Exposures) id was
published for horde3.
CVE-2009-3236[0]:
| Within the Horde Application Framework a special kind of form element
| exists that handles image file uploads. This form element if for
| example used within the Turba address book application. These form
| elements usually move the uploaded image to some temporary file with
| a random name and verify that the file is indeed an image.
|
| Furthermore the Horde_Form_Type_image form element contains a feature
| that is meant to allow reusing the same temporary filename on reuploads.
| In order to support this the previously used temporary filename is
| stored inside hidden form fields and which is then trusted during
| upload processing.
|
| /* Get any existing values for the image upload field. */
| $upload = $vars->get($var->getVarName());
| $upload['img'] = @unserialize($upload['img']);
|
| /* Get the temp file if already one uploaded, otherwise create a
| * new temporary file. */
| if (!empty($upload['img']['file'])) {
| $tmp_file = Horde::getTempDir() . '/' . $upload['img']['file'];
| } else {
| $tmp_file = Horde::getTempFile('Horde', false);
| }
|
| /* Move the browser created temp file to the new temp file. */
| move_uploaded_file($this->_img['file'], $tmp_file);
| $this->_img['file'] = basename($tmp_file);
|
| The code snippet above demonstrates how the previously used temporary
| filename is extracted from the user supplied serialized array and then
| used as new temporary filename. It should be obvious that this allows
| writing to any writable file on the webserver. Additionally the code
| only remembers the basename() of the filename which does not contain
| the path. Therefore the later attempt to delete invalid images fails.
|
| Aside from the file overwrite problem the second problem is that the
| PHP function unserialize() is used on user supplied input which can
| be used for other things like crashing PHP through deeply nested array
| structures.
This information is from the reporter advisory, the cve id description
isn't yet online. I attached the upstream patch that was used to fix
this issue. Please test it if you use it.
If you fix the vulnerability please also make sure to include the
CVE id in your changelog entry.
For further information see:
[0] http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2009-3236
http://security-tracker.debian.net/tracker/CVE-2009-3236
--
Nico Golde - http://www.ngolde.de - n...@jabber.ccc.de - GPG: 0xA0A0AAAA
For security reasons, all text in this mail is double-rot13 encrypted.
diff -Nurad horde-3.2.4/lib/Horde/Form.php horde-3.2.5/lib/Horde/Form.php
--- horde-3.2.4/lib/Horde/Form.php 2009-01-27 16:14:18.000000000 +0100
+++ horde-3.2.5/lib/Horde/Form.php 2009-09-14 10:10:30.000000000 +0200
@@ -1648,7 +1648,14 @@
*
* @var array
*/
- var $_img = array();
+ var $_img;
+
+ /**
+ * A random id that identifies the image information in the session data.
+ *
+ * @var string
+ */
+ var $_random;
function init($show_upload = true, $show_keeporig = false, $max_filesize =
null)
{
@@ -1660,7 +1667,7 @@
function onSubmit(&$var, &$vars)
{
/* Get the upload. */
- $this->_getUpload($vars, $var);
+ $this->getImage($vars, $var);
/* If this was done through the upload button override the submitted
* value of the form. */
@@ -1671,25 +1678,24 @@
function isValid(&$var, &$vars, $value, &$message)
{
- $field = $vars->get($var->getVarName());
-
/* Get the upload. */
- $this->_getUpload($vars, $var);
+ $this->getImage($vars, $var);
+ $field = $vars->get($var->getVarName());
/* The upload generated a PEAR Error. */
if (is_a($this->_uploaded, 'PEAR_Error')) {
/* Not required and no image upload attempted. */
- if (!$var->isRequired() && empty($field['img']) &&
+ if (!$var->isRequired() && empty($field['hash']) &&
$this->_uploaded->getCode() == UPLOAD_ERR_NO_FILE) {
return true;
}
if (($this->_uploaded->getCode() == UPLOAD_ERR_NO_FILE) &&
- empty($field['img'])) {
+ empty($field['hash'])) {
/* Nothing uploaded and no older upload. */
$message = _("This field is required.");
return false;
- } elseif (!empty($field['img'])) {
+ } elseif (!empty($field['hash'])) {
/* Nothing uploaded but older upload present. */
return true;
} else {
@@ -1697,11 +1703,11 @@
$message = $this->_uploaded->getMessage();
return false;
}
- } elseif (empty($this->_img['size'])) {
+ } elseif (empty($this->_img['img']['size'])) {
$message = _("The image file size could not be determined or it
was 0 bytes. The upload may have been interrupted.");
return false;
} elseif ($this->_max_filesize &&
- $this->_img['size'] > $this->_max_filesize) {
+ $this->_img['img']['size'] > $this->_max_filesize) {
$message = sprintf(_("The image file was larger than the maximum
allowed size (%d bytes)."), $this->_max_filesize);
return false;
}
@@ -1712,11 +1718,11 @@
function getInfo(&$vars, &$var, &$info)
{
/* Get the upload. */
- $this->_getUpload($vars, $var);
+ $this->getImage($vars, $var);
/* Get image params stored in the hidden field. */
$value = $var->getValue($vars);
- $info = $this->_img;
+ $info = $this->_img['img'];
if (empty($info['file'])) {
unset($info['file']);
return;
@@ -1771,7 +1777,7 @@
if ($this->_uploaded === true) {
/* A file has been uploaded on this submit. Save to temp dir for
* preview work. */
- $this->_img['type'] = $this->getUploadedFileType($varname .
'[new]');
+ $this->_img['img']['type'] = $this->getUploadedFileType($varname .
'[new]');
/* Get the other parts of the upload. */
require_once 'Horde/Array.php';
@@ -1779,19 +1785,22 @@
/* Get the temporary file name. */
$keys_path = array_merge(array($base, 'tmp_name'), $keys);
- $this->_img['file'] = Horde_Array::getElement($_FILES, $keys_path);
+ $this->_img['img']['file'] = Horde_Array::getElement($_FILES,
$keys_path);
/* Get the actual file name. */
- $keys_path= array_merge(array($base, 'name'), $keys);
- $this->_img['name'] = Horde_Array::getElement($_FILES, $keys_path);
+ $keys_path = array_merge(array($base, 'name'), $keys);
+ $this->_img['img']['name'] = Horde_Array::getElement($_FILES,
$keys_path);
/* Get the file size. */
- $keys_path= array_merge(array($base, 'size'), $keys);
- $this->_img['size'] = Horde_Array::getElement($_FILES, $keys_path);
+ $keys_path = array_merge(array($base, 'size'), $keys);
+ $this->_img['img']['size'] = Horde_Array::getElement($_FILES,
$keys_path);
/* Get any existing values for the image upload field. */
$upload = $vars->get($var->getVarName());
- $upload['img'] = @unserialize($upload['img']);
+ if (!empty($upload['hash'])) {
+ $upload['img'] = $_SESSION['horde_form'][$upload['hash']];
+ unset($_SESSION['horde_form'][$upload['hash']]);
+ }
/* Get the temp file if already one uploaded, otherwise create a
* new temporary file. */
@@ -1802,19 +1811,21 @@
}
/* Move the browser created temp file to the new temp file. */
- move_uploaded_file($this->_img['file'], $tmp_file);
- $this->_img['file'] = basename($tmp_file);
-
- /* Store the uploaded image file data to the hidden field. */
- $upload['img'] = serialize($this->_img);
- $vars->set($var->getVarName(), $upload);
+ move_uploaded_file($this->_img['img']['file'], $tmp_file);
+ $this->_img['img']['file'] = basename($tmp_file);
} elseif ($this->_uploaded) {
/* File has not been uploaded. */
$upload = $vars->get($var->getVarName());
- if ($this->_uploaded->getCode() == 4 && !empty($upload['img'])) {
- $this->_img = @unserialize($upload['img']);
+ if ($this->_uploaded->getCode() == 4 &&
+ !empty($upload['hash']) &&
+ isset($_SESSION['horde_form'][$upload['hash']])) {
+ $this->_img['img'] = $_SESSION['horde_form'][$upload['hash']];
+ unset($_SESSION['horde_form'][$upload['hash']]);
}
}
+ if (isset($this->_img['img'])) {
+ $_SESSION['horde_form'][$this->getRandomId()] = $this->_img['img'];
+ }
}
function getUploadedFileType($field)
@@ -1865,6 +1876,27 @@
}
/**
+ * Returns the current image information.
+ *
+ * @return array The current image hash.
+ */
+ function getImage($vars, $var)
+ {
+ $this->_getUpload($vars, $var);
+ if (!isset($this->_img)) {
+ $image = $vars->get($var->getVarName());
+ if ($image) {
+ $this->loadImageData($image);
+ if (isset($image['img'])) {
+ $this->_img = $image;
+ $_SESSION['horde_form'][$this->getRandomId()] =
$this->_img['img'];
+ }
+ }
+ }
+ return $this->_img;
+ }
+
+ /**
* Loads any existing image data into the image field. Requires that the
* array $image passed to it contains the structure:
* $image['load']['file'] - the filename of the image;
@@ -1886,10 +1918,18 @@
fclose($fd);
}
- $image['img'] = serialize(array('file' => $image['load']['file']));
+ $image['img'] = array('file' => $image['load']['file']);
unset($image['load']);
}
+ function getRandomId()
+ {
+ if (!isset($this->_random)) {
+ $this->_random = uniqid(mt_rand());
+ }
+ return $this->_random;
+ }
+
/**
* Return info about field type.
*/
pgp9AbJmBgY5L.pgp
Description: PGP signature
--- End Message ---
--- Begin Message ---
Source: horde3
Source-Version: 3.1.3-4etch6
We believe that the bug you reported is fixed in the latest version of
horde3, which is due to be installed in the Debian FTP archive:
horde3_3.1.3-4etch6.diff.gz
to pool/main/h/horde3/horde3_3.1.3-4etch6.diff.gz
horde3_3.1.3-4etch6.dsc
to pool/main/h/horde3/horde3_3.1.3-4etch6.dsc
horde3_3.1.3-4etch6_all.deb
to pool/main/h/horde3/horde3_3.1.3-4etch6_all.deb
A summary of the changes between this version and the previous one is
attached.
Thank you for reporting the bug, which will now be closed. If you
have further comments please address them to 547...@bugs.debian.org,
and the maintainer will reopen the bug report if appropriate.
Debian distribution maintenance software
pp.
Gregory Colpart <r...@debian.org> (supplier of updated horde3 package)
(This message was generated automatically at their request; if you
believe that there is a problem with it please contact the archive
administrators by mailing ftpmas...@debian.org)
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Format: 1.8
Date: Wed, 23 Sep 2009 00:51:33 +0200
Source: horde3
Binary: horde3
Architecture: source all
Version: 3.1.3-4etch6
Distribution: oldstable-security
Urgency: high
Maintainer: Horde Maintainers <pkg-horde-hack...@lists.alioth.debian.org>
Changed-By: Gregory Colpart <r...@debian.org>
Description:
horde3 - horde web application framework
Closes: 547318
Changes:
horde3 (3.1.3-4etch6) oldstable-security; urgency=high
.
* Backport security patch from Horde to fix vulnerability in image
form fields that allows overwriting of arbitrary local files. See
CVE-2009-3236 for more information. (Closes: #547318)
Checksums-Sha1:
a58c404ef470f6fbf5d8d06b400d19133748674e 1076 horde3_3.1.3-4etch6.dsc
1fb8e8f8f0c5df6b9f0d838f0af07f6d1013399d 15869 horde3_3.1.3-4etch6.diff.gz
3448d2b5e6a8ee47b43c5b0a9a03da2cff62b941 5278984 horde3_3.1.3-4etch6_all.deb
Checksums-Sha256:
656086ed1cdb1269f821f8a1133da0651e7437effbbf1c0fb137f38c8c63490e 1076
horde3_3.1.3-4etch6.dsc
29abd938153f2c8c529898664de123f967dfece89be9ae6ff1ba2a0cea1fbf8f 15869
horde3_3.1.3-4etch6.diff.gz
383c98db0bb236d6a5a3bc2446b7c930a6275760b374f95321d35b11172485e7 5278984
horde3_3.1.3-4etch6_all.deb
Files:
d4205b4f956ee00aa545f988f5d0206f 1076 web optional horde3_3.1.3-4etch6.dsc
3a74c50d35cf7f252cceec008e133299 15869 web optional horde3_3.1.3-4etch6.diff.gz
55bb80d663cad92d40ffcd15946379cf 5278984 web optional
horde3_3.1.3-4etch6_all.deb
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
iEYEARECAAYFAkq6nvAACgkQMhdcDcECeg528gCdFPlvvobCDfSPR7jhvsdn/crr
8HgAnA6hijv0aevIclWJcSjLcoYKmIQ4
=iP1j
-----END PGP SIGNATURE-----
--- End Message ---