[VPM] alternative to perl's Open?

abez abez at abez.ca
Tue Sep 7 11:38:55 CDT 2004


You must have an older version of CGI.pm because the source code only
opens a temporary file they created.


sub read_multipart {
    my($self,$boundary,$length) = @_;
    my($buffer) = new MultipartBuffer($boundary,$length);
    my(%header,$body);
    while (!$buffer->eof) {
	%header = $buffer->readHeader;
	# In beta1 it was "Content-disposition".  In beta2 it's
	# "Content-Disposition"
	# Sheesh.
	my($key) = $header{'Content-disposition'} ?
'Content-disposition' : 'Content-Disposition';
	my($param) = $header{$key}=~/ name="(.*?)"/;
	my($filename) = $header{$key}=~/ filename="(.*?)"/;

	# add this parameter to our list
	$self->add_parameter($param);

	# If no filename specified, then just read the data and assign
	# it
	# to our parameter list.
	unless ($filename) {
	    my($value) = $buffer->readBody;
	    push(@{$self->{$param}},$value);
	    next;
	}

	# If we get here, then we are dealing with a potentially large
	# uploaded form.  Save the data to a temporary file, then open
	# the file for reading.
	my($tmpfile) = new TempFile;
	open (OUT,">$tmpfile") || die "CGI open of $tmpfile: $!\n";
	chmod 0666,$tmpfile;	# make sure anyone can delete it.
	my $data;
	while ($data = $buffer->read) {
	    print OUT $data;
	}
	close OUT;

	# Now create a new filehandle in the caller's namespace.
	# The name of this filehandle just happens to be identical
	# to the original filename (NOT the name of the temporary
	# file, which is hidden!)
	my($frame)=1;
	my($cp);
	do {
	    $cp = caller($frame++);
	} until $cp!~/^CGI/;
	my($filehandle) = "$cp\:\:$filename";
	open($filehandle,$tmpfile) || die "CGI open of $tmpfile: $!\n";
	push(@{$self->{$param}},$filename);

	# Under Unix, it would be safe to let the temporary file
	# be deleted immediately.  However, I fear that other operating
	# systems are not so forgiving.  Therefore we save a reference
	# to the temporary file in the CGI object so that the file
	# isn't unlinked until the CGI object itself goes out of
	# scope.  This is a bit hacky.
	$self->{"$tmpfile"}=$tmpfile;

    }

}


On Tue, 7 Sep 2004, Carl B. Constantine wrote:

> *On Tue Sep 07, 2004 at 09:24:55AM -0700, abez (abez at abez.ca) wrote:
> > 
> > >From CGI.pm 
> > 	  my $query = CGI->new;
> > 	  $filename = $query->param('uploaded_file');
> > 	  while(<$filename>) { print; }
> > 
> > The file is saved to a tmp dir and then opened. $filename is the file
> > handle. It doesn't matter what the user named their file.
> > 	
> > If you are running perl code that other people supply you really can't
> > stop much. For instance they could have just forked a telnet daemon.
> > 
> > I'd suggest running the perl scripts under a user who didn't have
> > privileges to anything. 
> 
> They did just that. It was a user CGI (we use suExec) and they used a
> pipe command to wget to get their stuff and run a daemon program
> backdoor for entry into the box.
> 
> It was quite nasty.
> 
> > chroot can also help you. 
> > 
> > So make a little mini installation of perl. When you run a script chroot
> > to the sandbox and setuid to something very weak.
> 
> Not sure that's doable in this situation, but I'll look into it.
> 
> 

-- 
abez ------------------------------------------
http://www.abez.ca/ Abram Hindle (abez at abez.ca)
------------------------------------------ abez



More information about the Victoria-pm mailing list