Package: openwebmail Priority: grave Version: 2.41-10 Tags: patch security Openwebmail has multiple unsafe usages of temporary files (in /tmp) which lead to race conditions and symlink attacks. There are actually a lot of Perl scripts that, instead of using Perl's builtin File::Temp module use the (insecure) /tmp/SOMETHING.$$$ construct to define temporary files.
Attached is a patch fixing some of these issues, it doesn't fix all of them, however. To find remaining issues please run 'grep -r "/tmp" .' on the source directory. The patch should provide hints on how to properly fix all of these. IMHO these bugs together with #290848 show that there has been no effort to prevent security bugs and makes this package unsuitable for release with sarge. I don't think this package should be included in a Debian release unless a full audit has been conducted in the sources for common web programming mistakes. Regards Javier
diff -Nru openwebmail-2.41.orig/cgi-bin/openwebmail/misc/mkrelease/mkcurrent.sh openwebmail-2.41/cgi-bin/openwebmail/misc/mkrelease/mkcurrent.sh --- openwebmail-2.41.orig/cgi-bin/openwebmail/misc/mkrelease/mkcurrent.sh 2004-08-05 05:07:27.000000000 +0200 +++ openwebmail-2.41/cgi-bin/openwebmail/misc/mkrelease/mkcurrent.sh 2005-01-21 01:12:54.000000000 +0100 @@ -3,9 +3,8 @@ # this is used by author to create the tarball of openwebmail # -tmpdir=/tmp/openwebmail.mkrelease.tmp -rm -Rf $tmpdir -mkdir $tmpdir +tmpdir=`mktemp -d openwebmail.mkrelease.XXXXXX` || { echo "$0: Cannot create temporary directory" >&2 ; exit 1; } +trap "rm -rf $tmpdir" 0 1 2 3 13 15 cd $tmpdir q /usr/local/www/cgi-bin/openwebmail/etc/defaults/openwebmail.conf @@ -193,10 +192,11 @@ echo copy current to snapshot $version-$releasedate... cd /usr/local/www/data/openwebmail/download/snapshot cp /usr/local/www/data/openwebmail/download/current/openwebmail-current.tar.gz openwebmail-$version-$releasedate.tar.gz - grep -v $releasedate MD5SUM >/tmp/.md5.tmp.$$ - md5 -r openwebmail-$version-$releasedate.tar.gz >> /tmp/.md5.tmp.$$ - cp /tmp/.md5.tmp.$$ MD5SUM - rm /tmp/.md5.tmp.$$ + md5file=`mktemp -t .md5.tmp.XXXXXX` || { echo "$0: Cannot create temporary file" >&2; exit 1; } + grep -v $releasedate MD5SUM >$md5file + md5 -r openwebmail-$version-$releasedate.tar.gz >> $md5file + cp $md5file MD5SUM + rm -f $md5file fi ################################################################# diff -Nru openwebmail-2.41.orig/cgi-bin/openwebmail/misc/mkrelease/notify.sh openwebmail-2.41/cgi-bin/openwebmail/misc/mkrelease/notify.sh --- openwebmail-2.41.orig/cgi-bin/openwebmail/misc/mkrelease/notify.sh 2004-09-21 18:09:31.000000000 +0200 +++ openwebmail-2.41/cgi-bin/openwebmail/misc/mkrelease/notify.sh 2005-01-21 01:10:02.000000000 +0100 @@ -115,6 +115,8 @@ echo "send release announcement to port maintainer? (y/N)" read ans if [ "$ans" = "y" -o "$ans" = "Y" ]; then + notify=`mktemp -t notify.XXXXXX` || { echo "$0: Cannot create temporary file" >&2; exit 1; } + trap "rm -f $notify" 0 1 2 3 13 15 echo "Dear sir, The new release of Open WebMail is available now. @@ -132,17 +134,16 @@ Best Regards. tung -" >/tmp/notify.tmp.$$ +" >$notify - q /tmp/notify.tmp.$$ + q $notify echo "Really send release announcement to port maintainer? (y/N)" read ans if [ "$ans" = "y" -o "$ans" = "Y" ]; then echo sending to pkg/port maintainer... - cat /tmp/notify.tmp.$$| \ + cat $notify| \ /usr/local/bin/mutt -s "OWM new release announcement" \ $cobalt $freebsd $openbsd $debian $webmin $ipspace fi - rm /tmp/notify.tmp.$$ fi diff -Nru openwebmail-2.41.orig/cgi-bin/openwebmail/misc/test/dbmtest.pl openwebmail-2.41/cgi-bin/openwebmail/misc/test/dbmtest.pl --- openwebmail-2.41.orig/cgi-bin/openwebmail/misc/test/dbmtest.pl 2004-07-07 15:22:13.000000000 +0200 +++ openwebmail-2.41/cgi-bin/openwebmail/misc/test/dbmtest.pl 2005-01-21 01:07:52.000000000 +0100 @@ -5,6 +5,7 @@ use strict; use Fcntl qw(:DEFAULT :flock); use FileHandle; +use File::Temp qw/tempfile tempdir/; print "\n"; @@ -21,9 +22,10 @@ sub check_tell_bug { my $offset; - my $testfile="/tmp/testfile.$$"; + my ($testh, $testfile) = tempfile ("testfile.XXXXXX"); ($testfile =~ /^(.+)$/) && ($testfile = $1); + close $testh; open(F, ">$testfile"); print F "test"; close(F); open(F, ">>$testfile"); $offset=tell(F); close(F); unlink($testfile); @@ -42,18 +44,17 @@ sub guessoptions { my (%DB, @filelist, @delfiles); my ($dbm_ext, $dbmopen_ext, $dbmopen_haslock); + my $dbmdir = tempdir("dbmtest.XXXXXX"); - mkdir ("/tmp/dbmtest.$$", 0755); - - dbmopen(%DB, "/tmp/dbmtest.$$/test", 0600); dbmclose(%DB); + dbmopen(%DB, "$dbmdir/test", 0600); dbmclose(%DB); @delfiles=(); - opendir(TESTDIR, "/tmp/dbmtest.$$"); + opendir(TESTDIR, "$dbmdir"); while (defined(my $filename = readdir(TESTDIR))) { ($filename =~ /^(.+)$/) && ($filename = $1); # untaint ... if ($filename!~/^\./ ) { push(@filelist, $filename); - push(@delfiles, "/tmp/dbmtest.$$/$filename"); + push(@delfiles, $dbmdir."/$filename"); } } closedir(TESTDIR); @@ -67,11 +68,11 @@ } my $result; - flock_lock("/tmp/dbmtest.$$/test$dbm_ext", LOCK_EX); + flock_lock($dbmdir."/test$dbm_ext", LOCK_EX); eval { local $SIG{ALRM} = sub { die "alarm\n" }; # NB: \n required alarm 5; # timeout 5 sec - $result = dbmopen(%DB, "/tmp/dbmtest.$$/test$dbmopen_ext", 0600); + $result = dbmopen(%DB, $dbmdir."/test$dbmopen_ext", 0600); dbmclose(%DB) if ($result); alarm 0; }; @@ -80,18 +81,18 @@ } else { $dbmopen_haslock=0; } - flock_lock("/tmp/dbmtest.$$/test$dbm_ext", LOCK_UN); + flock_lock($dbmdir."/test$dbm_ext", LOCK_UN); @delfiles=(); - opendir(TESTDIR, "/tmp/dbmtest.$$"); + opendir(TESTDIR, "$dbmdir"); while (defined(my $filename = readdir(TESTDIR))) { ($filename =~ /^(.+)$/) && ($filename = $1); # untaint ... - push(@delfiles, "/tmp/dbmtest.$$/$filename") if ($filename!~/^\./ ); + push(@delfiles, $dbmdir."/$filename") if ($filename!~/^\./ ); } closedir(TESTDIR); unlink(@delfiles) if ($#delfiles>=0); - rmdir("/tmp/dbmtest.$$"); + rmdir("$dbmdir"); return($dbm_ext, $dbmopen_ext, $dbmopen_haslock); } diff -Nru openwebmail-2.41.orig/cgi-bin/openwebmail/misc/tools/mkcool3d/mkcool3d_en.sh openwebmail-2.41/cgi-bin/openwebmail/misc/tools/mkcool3d/mkcool3d_en.sh --- openwebmail-2.41.orig/cgi-bin/openwebmail/misc/tools/mkcool3d/mkcool3d_en.sh 2004-08-06 20:18:24.000000000 +0200 +++ openwebmail-2.41/cgi-bin/openwebmail/misc/tools/mkcool3d/mkcool3d_en.sh 2005-01-21 01:15:27.000000000 +0100 @@ -9,6 +9,10 @@ # choose the destination dir of icons DEST=Cool3D.English +# Temporary directory +ROOT=`mktemp -d cool.XXXXXX` || { echo "$0: Cannot create temporary directory" >&2; exit 1; } +trap "rm -rf $ROOT" 0 1 2 3 13 15 + # # BEGIN OF SCRIPT @@ -22,11 +26,11 @@ STARTICON=$2 BLANKICON=Cool3D/blank.gif - GBASEFILE=/tmp/base - GCUTFILE=/tmp/cut - GTEXTFILE=/tmp/text - GFINALFILE=/tmp/final - GALPHAFILE=/tmp/alpha + GBASEFILE=$ROOT/base + GCUTFILE=$ROOT/cut + GTEXTFILE=$ROOT/text + GFINALFILE=$ROOT/final + GALPHAFILE=$ROOT/alpha # find transparent color (must be imposed because in blank.gif transparent color is not defined) # TRCOLOR=`giftopnm -verbose $BLANKICON 2>&1 | head -n 1 | cut -s -d " " -f 5 | cut -s -d ":" -f 2 | tr -d /` Los ficheros binarios openwebmail-2.41.orig/cgi-bin/openwebmail/misc/tools/mkcool3d/.mkcool3d_en.sh.swp y openwebmail-2.41/cgi-bin/openwebmail/misc/tools/mkcool3d/.mkcool3d_en.sh.swp son distintos diff -Nru openwebmail-2.41.orig/cgi-bin/openwebmail/misc/tools/mkcool3d/mkcool3d.sh openwebmail-2.41/cgi-bin/openwebmail/misc/tools/mkcool3d/mkcool3d.sh --- openwebmail-2.41.orig/cgi-bin/openwebmail/misc/tools/mkcool3d/mkcool3d.sh 2004-08-06 20:18:24.000000000 +0200 +++ openwebmail-2.41/cgi-bin/openwebmail/misc/tools/mkcool3d/mkcool3d.sh 2005-01-21 01:14:36.000000000 +0100 @@ -79,7 +79,8 @@ fi # Temporary directory -ROOT=/tmp +ROOT=`mktemp -d cool.XXXXXX` || { echo "$0: Cannot create temporary directory" >&2; exit 1; } +trap "rm -rf $ROOT" 0 1 2 3 13 15 # Destination dir of icons DEST=Cool3D.$LANGLONG diff -Nru openwebmail-2.41.orig/cgi-bin/openwebmail/openwebmail-folder.pl openwebmail-2.41/cgi-bin/openwebmail/openwebmail-folder.pl --- openwebmail-2.41.orig/cgi-bin/openwebmail/openwebmail-folder.pl 2005-01-21 00:43:15.000000000 +0100 +++ openwebmail-2.41/cgi-bin/openwebmail/openwebmail-folder.pl 2005-01-21 00:57:12.000000000 +0100 @@ -18,6 +18,7 @@ use Fcntl qw(:DEFAULT :flock); use CGI qw(-private_tempfiles :standard); use CGI::Carp qw(fatalsToBrowser carpout); +use File::Temp qw/tempfile/; require "modules/dbm.pl"; require "modules/suid.pl"; @@ -354,13 +355,15 @@ ow::dbm::close(\%FDB, $folderdb); my @unreadmsgids=(sort { $offset{$a}<=>$offset{$b} } keys %offset); - my $tmpfile=ow::tool::untaint("/tmp/.markread.tmpfile.$$"); - my $tmpdb=ow::tool::untaint("/tmp/.markread.tmpdb.$$"); + my ($tmpfh, $tmpfile ) = tempfile(".markread.tmpfile.XXXXXX"); + my ($tmpdbh, $tmpdb ) = tempfile(".markread.tmpdb.XXXXXX"); + $tmpfile=ow::tool::untaint($tmpfile); + $tmpdb=ow::tool::untaint($tmpdb); while (!$ioerr && $#unreadmsgids>=0) { my @markids=(); - open(F, ">$tmpfile"); close(F); + close $tmpfh; ow::filelock::lock($tmpfile, LOCK_EX) or openwebmailerror(__FILE__, __LINE__, "$lang_err{'couldnt_lock'} $tmpfile"); diff -Nru openwebmail-2.41.orig/cgi-bin/openwebmail/openwebmail-send.pl openwebmail-2.41/cgi-bin/openwebmail/openwebmail-send.pl --- openwebmail-2.41.orig/cgi-bin/openwebmail/openwebmail-send.pl 2005-01-21 00:43:15.000000000 +0100 +++ openwebmail-2.41/cgi-bin/openwebmail/openwebmail-send.pl 2005-01-21 00:54:34.000000000 +0100 @@ -21,6 +21,7 @@ use MIME::Base64; use MIME::QuotedPrint; use Net::SMTP; +use File::Temp qw/tempfile/; require "modules/dbm.pl"; require "modules/suid.pl"; @@ -1578,7 +1579,7 @@ my $saveerr=0; my $smtp; - my $smtperrfile="/tmp/.openwebmail.smtperr.$$"; + my ($smtperrh, $smtperrfile) = tempfile ("openwebmail.smtperr.XXXXXX"); local (*STDERR); # localize stderr to a new global variable my ($savefolder, $savefile, $savedb); @@ -1613,6 +1614,7 @@ # redirect stderr to smtperrfile $smtperrfile=ow::tool::untaint($smtperrfile); + close $smtperrh; open(STDERR, ">$smtperrfile"); select(STDERR); local $| = 1; select(STDOUT); diff -Nru openwebmail-2.41.orig/cgi-bin/openwebmail/openwebmail-tool.pl openwebmail-2.41/cgi-bin/openwebmail/openwebmail-tool.pl --- openwebmail-2.41.orig/cgi-bin/openwebmail/openwebmail-tool.pl 2005-01-21 00:43:15.000000000 +0100 +++ openwebmail-2.41/cgi-bin/openwebmail/openwebmail-tool.pl 2005-01-21 00:52:08.000000000 +0100 @@ -28,6 +28,7 @@ use strict; use Fcntl qw(:DEFAULT :flock); use Net::SMTP; +use File::Temp qw/tempfile/; require "modules/dbm.pl"; require "modules/suid.pl"; @@ -347,9 +348,8 @@ sub check_tell_bug { my $offset; - my $testfile=ow::tool::untaint("/tmp/testfile.$$"); - - open(F, ">$testfile"); print F "test"; close(F); + my ($testh, $testfile) = tempfile ( "testfile.XXXXXX"); + print $testh "test"; close $testh; open(F, ">>$testfile"); $offset=tell(F); close(F); unlink($testfile); diff -Nru openwebmail-2.41.orig/cgi-bin/openwebmail/openwebmail-viewatt.pl openwebmail-2.41/cgi-bin/openwebmail/openwebmail-viewatt.pl --- openwebmail-2.41.orig/cgi-bin/openwebmail/openwebmail-viewatt.pl 2005-01-21 00:43:15.000000000 +0100 +++ openwebmail-2.41/cgi-bin/openwebmail/openwebmail-viewatt.pl 2005-01-21 00:50:06.000000000 +0100 @@ -20,6 +20,7 @@ use CGI::Carp qw(fatalsToBrowser carpout); use MIME::Base64; use MIME::QuotedPrint; +use File::Temp; require "modules/dbm.pl"; require "modules/suid.pl"; @@ -420,11 +421,10 @@ my $antiwordbin=ow::tool::findbin('antiword'); return 0 if ($antiwordbin eq ''); - my $tmpfile=ow::tool::untaint("/tmp/.msword2html.tmpfile.$$"); + my ($tmph, $tmpfile) = tempfile ( "msword2html.XXXXXX" ); my $err=0; - open(F, ">$tmpfile") or return 0; - print F ${$r_content} or $err++; - close(F); + print $tmph ${$r_content} or $err++; + close $tmph; if ($err) { unlink($tmpfile); return 0; diff -Nru openwebmail-2.41.orig/cgi-bin/openwebmail/vacation.pl openwebmail-2.41/cgi-bin/openwebmail/vacation.pl --- openwebmail-2.41.orig/cgi-bin/openwebmail/vacation.pl 2004-08-18 11:34:47.000000000 +0200 +++ openwebmail-2.41/cgi-bin/openwebmail/vacation.pl 2005-01-21 01:01:30.000000000 +0100 @@ -38,7 +38,7 @@ # -p homepath Specify a directory for the user home. # (mostly for virtual user with no real unix home) # -# -d log debug information to /tmp/vacation.debug +# -d log debug information to $TMPDIR/vacation.debug # # The options -a and -f can be specified for more than one times. # @@ -74,6 +74,7 @@ # use strict; +use File::Spec; foreach (qw(ENV BASH_ENV CDPATH IFS TERM)) {delete $ENV{$_}}; $ENV{PATH}='/bin:/usr/bin'; # secure ENV my $myname = $0; @@ -131,7 +132,7 @@ $_ = shift; if (/^-I/i) { # eric allman's source has both cases $opt_i=1; - } elsif (/^-d/) { # log debug information to /tmp/vacation.debug + } elsif (/^-d/) { # log debug information to $TMPDIR/vacation.debug $opt_d=1; } elsif (/^-j/) { # don't check if user is a valid receiver $opt_j=1; @@ -589,12 +590,17 @@ my @[EMAIL PROTECTED]; my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst); my ($today, $time); + # Use tmpdir which helps users prevent symlink attacks + # if they set $TMPDIR properly + my $tmpdir = File::Spec->tmpdir(); + my $debugfile = $tmpdir."/vacation.debug"; ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =localtime; $today=sprintf("%4d%02d%02d", $year+1900, $mon+1, $mday); $time=sprintf("%02d%02d%02d",$hour,$min, $sec); - open(Z, ">> /tmp/vacation.debug"); + # Not safe if tmpdir is in an unsafe location + open(Z, ">> $debugfile"); # unbuffer mode select(Z); local $| = 1; @@ -603,6 +609,6 @@ print Z "$today $time ", join(" ",@msg), "\n"; close(Z); - chmod(0666, "/tmp/vacation.debug"); + chmod(0666, "$debugfile"); }
signature.asc
Description: Digital signature