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");
 }
 

Attachment: signature.asc
Description: Digital signature

Reply via email to