Uploading files is a semi-complex process involving the right incantations on both the client forms and the server - but it can be tamed. Here's a quick over view of what you need to have to accept file uploads.

Example "simple" upload form...

<form name="UploadForm" method="post" action="./file.cgi"

enctype="multipart/form-data" >





You must be using a browser and server that supports HTTP 1.1 (Apache 1.3.x

and IIS 4.0. 3.x Netscape and above and 3.02? IE and above). Note that the

upload form needs a enctype. For file uploads you need



It's best that you use a CGI library like cgi-lib.pl or CGI.pm to assist you in

uploading files. These libraries can help you limit the file sizes and upload

locations as well as other niceties that will make the process






I'm partial to cgi-lib because its a smaller library and I only currently use the

upload and form parsing functions. But both libraries are very good.


An understanding that you are allowing anonymous (unless the upload area

is password protected) people to upload files to your server. Make sure you

write code that chmod's the files to 666 or some other type of readable but

not executable form. Check for .cgi , .pl for extensions and strip them off.

Look for shebangs in the first line of all files - remove them or quarantine

them. Also, people have the potential to upload malicious HTML pages and

other 'tainted' stuff.


Be paranoid. God is always building a better idiot.

After constructing the proper form, everything else is set within the CGI program. With cgi-lib.pl you have the following variables that can be set to control the upload process: (There are more than these variables that can be set - read the library's documentation to ferret out all the other options.)

# Spool the files to the ______ directory

# (directory needs to be 777)

$cgi_lib::writefiles = "/full/path/to/upload/dir";

# Limit upload size

$cgi_lib::maxdata = 50000000;

# set to 50 megs;

The Upload directory is a "temp" location and the files are given unique names by the web server 23455.1 for file number one and 23455.2 for file number two (if you are doing multi-uploads). You are then responsible for getting the temp files renamed and put in their proper locations.

By parsing the form you can glean all the info you need to rename the files back to their original names. Cgi-Lib.pl uses the following parse function:

# Reading and pare the data. Save the return value to $ret

# Pass references to retrieve the data, the filenames,

# and the content-type

$ret = &ReadParse(\%cgi_data,\%cgi_cfn,\%cgi_ct,\%cgi_sfn);


For example:

<FORM NAME=UPLOADFORM ENCTYPE="multipart/form-data"

ACTION="/cgi-bin/upload.cgi" METHOD="POST>

<INPUT TYPE="file" NAME="File1"> # User puts in: c:\autoexec.bat

<INPUT TYPE="file" NAME="File2"> # User puts in: c:\config.sys

<INPUT TYPE="file" NAME="File3"> # User puts in: c:\bootlog.txt

<INPUT TYPE="text" NAME="UserName"> # User puts in: Howdy Doody



** upload.cgi **


require 5.001;

require "cgi-lib.pl";

# Spool the files to the ______ directory

# (directory needs to be 777)

$cgi_lib::writefiles = "/tmp/uploads";

# Limit upload size

$cgi_lib::maxdata = 50;

# set to 50k ;

$ret = &ReadParse(\%cgi_data,\%cgi_cfn,\%cgi_ct,\%cgi_sfn);

** You would now have the following info...

$cgi_data{'UserName'} = "Howdy Doody"

$cgi_data{'File1'} = "/tmp/uploads/2343235.1"

$cgi_cfn{'File1'} = "c:\autoexec.bat"

$cgi_ct{'File1'} = "text/plain"

$cgi_sfn{'File1'} = "2343235.1"

$cgi_data{'File2'} = "/tmp/uploads/2343235.2"

$cgi_cfn{'File2'} = "c:\config.sys"

$cgi_ct{'File2'} = "text/plain"

$cgi_sfn{'File2'} = "2343235.2"

$cgi_data{'File3'} = "/tmp/uploads/2343235.3"

$cgi_cfn{'File3'} = "c:\bootlog.txt"

$cgi_ct{'File3'} = "text/plain"

$cgi_sfn{'File3'} = "2343235.3"

Hope this helps. Good Luck.