[dev] imp-2.2.4 tmpfile problems ?
Jarno Huuskonen
Jarno.Huuskonen@uku.fi
Fri, 18 May 2001 15:46:31 +0300
On Fri, May 18, Anil Madhavapeddy wrote:
> Jarno Huuskonen wrote:
> >
> > When user uploads an attachment file from the compose
> > message window first php creates a temporary file
> > (in upload_tmp_dir) usually the file will be something
> > like /tmp/phpXXXXXX. Now it's upto compose.php3 to copy
> > the file to safe place, and compose.php3 does this with
> > copy(safe_file(...), safe_file(...) . '.att'). The
> > problem is that the copy call is kind enough to follow
> > symlinks.
>
> The underlying system call used here by PHP4 is mkstemp(). glibc only
> accepts six X entries for randomness, which is why there are six there.
(AFAIK glibc-2.1.3 accepts more than six 'X' (it just uses the last six :)
I guess there is no problem with the actual file upload with php4, but the
problem is in the imp copy call (compose.php3:L915):
copy (safe_file($file_upload), safe_file($file_upload) . '.att');
^^^^^This is OK(at least w/php4), but the second argument (destination)
is just the original temporary filename with .att added to the end.
Example: php creates a temporary filename: /tmp/php2nRC4r so the copy call
will be:
copy('/tmp/php2nRC4r', '/tmp/php2nRC4r.att').
And the copy call does not check if the destination file '/tmp/php2nRC4r.att'
exists / is a symlink.
(OK I checked the php-4.0.5 source and it looks like that in safe mode
the copy call has some checks (but I still think that even with that there's
still temp-race)). Hope you can prove me wrong ;-)
> > All you have do is create bunch of /tmp/phpXXXXXX.att
> > symlinks and keep uploading attachments and you'll
> > end up (over)writing some file with webserver permissions.
>
> Hang on, this wont work. mkstemp() will never overwrite a symlink - it
> will create a unique filename, or fail.
See the .att in the linkname (php creates temporary filenames phpXXXXXX and
imp adds the .att (and imp doesn't use php_tempname/mkstemp)).
So do enough ln -s /nobody/writable/file /tmp/phpXXXXXX.att and pray that
it's your lucky day ;-) (OK ... It'll take time but eventually you'll get it
right).
> On OpenBSD at least, I've patched PHP4 to use 10 X characters, which
> makes it practically impossible to exploit.
>
> http://demo.horde.org/devel/horde/chora/checkout.php/ports/www/php4/patc
> hes/patch-main_php_open_temporary_file_c?rt=obsd&r=1.1
>
> > I noticed from the archive that Jon Parise has submitted
> > a patch for mimetypes.lib, so it'll use tempnam. Like I
> > mentioned above php-3.0.18 tempnam is not safe to use
> > (if the directory is world writable) because it has a temp-race
> > problem.
>
> All the temp problems are fixed (or will be, as soon as I commit the
> rest of the new MIME stuff) in 2.3.x, since Horde::getTempFile() will
> take care of securely creating a temporary file.
When is imp-2.3.x going to be stable ? I think quite a few sites still run
2.2.x w/php3 ...
Hmm, Would something like this work (for imp-2.2.4) (with more sanity checks):
--- horde-1.2.4/imp/compose.php3 Fri May 18 14:46:02 2001
+++ horde-1.2.4-jh/imp/compose.php3 Fri May 18 15:30:26 2001
@@ -905,14 +905,16 @@
if ($file_upload_size > 0) {
$attachments_name[] = $file_upload_name;
$attachments_size[] = $file_upload_size;
- $attachments_file[] = safe_file($file_upload) . '.att';
-
+ $tmpfile_name = tempnam(tmpdir(), 'impat');
+ $attachments_file[] = $tmpfile_name;
+
if (isset ($file_upload_type)) {
$attachments_type[] = $file_upload_type;
} else {
$attachments_type[] = '';
}
- copy (safe_file($file_upload), safe_file($file_upload) . '.att');
+ copy (safe_file($file_upload), $tmpfile_name);
+ chmod($tmpfile_name, 0600);
$msg = $message;
}
(with php-3.0.18 tempnam fixed to use mkstemp).
-Jarno
--
Jarno Huuskonen - System Administrator | Jarno.Huuskonen@uku.fi
University of Kuopio - Computer Center | Work: +358 17 162822
PO BOX 1627, 70211 Kuopio, Finland | Mobile: +358 40 5388169