Local
  Home
 WebMail
 Services
 Products
 TheVault
 Programming
 Downloads
 Web Tools
 Search
 Forum
 About
         
Hosted
  xtc4u.org
 jucifer.com
 corndogs.org
 elephant6.net
perlchest.com
 ofmontreal.net
 orangetwin.com
 darrenmobley.com
 cloudrecordings.com
 thelatebphelium.com
         
Check Email
.: News :.

Secure Programming



Perl



Perl is an excellent programming language to learn and use.
It is one of the most "Platform Independant" languages available, meaning
that it runs on most Operating Systems available, such as Unix, Linux, *BSD's,
Windows95/98/NT/2000 and even Macintosh computers.

Perl programming security...

There have been numerous holes in many poorly written perl/CGI scripts over
the years that have lead to the compromise of a system. Some of the most famous being
php.cgi , whois_raw.cgi, pfdisplay.cgi, etc...
The insecurity of these scripts was not the fault of Perl, but rather the programmer.
They emphasize the importance of checking all pieces of input the user could give, and poor parsing
of that data to not rule out certain characters such as ; | / .. and so on.

For good information on secure Perl/CGI programming, be sure to read http://www.perl.com/pub/doc/FAQs/cgi/www-security-faq.html for advice
and general guidelines to follow.

Here are just a few code snippets to help you while writing perl scripts.

Tips And Tricks :

Parsing User Data
This code is good for parsing user input from forms, especially email forms and anything else
that uses a system() call or other command which interacts with a shell.

read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
@pairs = split(/&/, $buffer);
foreach $pair (@pairs) {
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/~!/ ~!/g;
$value =~ s/<([^>]|\n)*>//g;
$value =~ s/([\&;\`'\\\|"*?~<>^\(\)\[\]\{\}\$\n\r])/\\$1/g;
$value =~ s/\0//g;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$FORM{$name} = $value;
}

$username=$FORM{'user'};
$password=$FORM{'pass'};


Environment Variables
This simple cgi script will show you all the environment variables. This is the same output as typing
'env' on a unix shell, when run from the command line, from a browser it shows all the HTTP variables.
#!/usr/bin/perl

print "Content-type: text/plain\n\n";
foreach $var (sort(keys(%ENV))) {
    $val = $ENV{$var};
    $val =~ s|\n|\\n|g;
    $val =~ s|"|\\"|g;
    print "${var}=\"${val}\"\n";
}

Here is a fairly accurate way to get the hostname and IP address of a remote user, vital to
authenticating a possibly "trusted" user or seeing who is visiting a page.
** note - This is a fully working script when used with SSI. You can see it in action
on the top-right of this page.
#!/usr/bin/perl

$message = "Your IP Adress : ";
$remote = "$ENV{'REMOTE_HOST'}";
$remote2 = "$ENV{'REMOTE_ADDR'}";

if ( ($remote eq $remote2) || ($remote eq '') ) {
  $remote = gethostbyaddr(pack('C4', split(/\./, $remote2)), 2) || $remote2;
  $ENV{'REMOTE_HOST'} = $remote;
}

print "Content-type: text/html\n\n";
print "$message $remote";


For forcing a script to use Non Parsed Headers (for Apache only), use this at the begining
of your script.
**note - this will let the cgi display it's output while running, rather than waiting for the
whole thing to finish.

#!/usr/bin/perl
$| = 1;
print "$ENV{'SERVER_PROTOCOL'} 200 OK\n";
print "Server: $ENV{'SERVER_SOFTWARE'}\n";
print "Content-type: text/html\n\n";


Example Snippets
The perl documents are great, but rarely do they provide a working example to go from,
which is IMHO the best way to learn.

File Operations :

This opens a file for reading only, locks the files contents so that it can not be overwritten
while it's being read from (a problem that a lot of cgi counters have), puts the file contents
line by line into @info,
then releases the lock on the file and close the file.
** note - the flock() function only works on unix - like systems, not in Windows
open(FILE, "</path/to/inputfile.txt");
flock FILE, 2;
@info = ;
flock FILE, 8;
close(FILE);
The line open(FILE, "</path/to/inputfile.txt"); use < to represent open for reading.
> is for writing, if file doesn't not exist, create it, if it does exist, write over it.
>> is for appending, being created if not present, writing to the end of the file.
+< is for both read/write updates to a file. ( +> clobbers the file first )
See this for more info on
the open() function.

Often you might want to call a cgi script by itself, then be able format a html form within the cgi
to send more data back to it. This is a cgi that will crypt a passwd for you to use with .htpasswd files.

** note - see this in action here
Its also very important the the _EOF_ and _EOF2_ are flush with the left margin if the
page, a simple copy/paste won't work with this...

#!/usr/bin/perl
#
# Simple little crypt function for .htaccess stuff
#
$cgi_url = "http://www.n3t.net/cgi-bin/crypt.cgi";


read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
@pairs = split(/&/, $buffer);
foreach $pair (@pairs) {
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$value =~ s/~!/ ~!/g;
$value =~ s/<([^>]|\n)*>//g;
$value =~ s/([;<>\*\|`&\$!#\(\)\[\]\{\}:'"\n])/\\$1/g;
$FORM{$name} = $value;
}

if($FORM{'action'} eq '') {

print "Content-type: text/html\n\n";
print <<"_EOF1_"

<html><title>DES Crypt</title><body>
<html><head><title>WebUtil Ping</title></head>
<body bgcolor="#000000" text="#FFFFFF">
<b>DES crypt</b> by: dlm21
<form method="POST" action="$cgi_url">
<input type="hidden" name="action" value="doit">
Username <input type="text" name="user" value="" size="20">
Password <input type=text name="passwd" value="" size="20">
<p>
<input type=submit value=" crypt "> <input type=reset>
</form>
</body></html>

_EOF1_
;
exit;
}

elsif($FORM{'action'} eq 'doit') {

$user = $FORM{'user'};
$pass = $FORM{'passwd'};
$passwd = crypt($pass,$user);
print "Content-type: text/html\n\n";
print <<"_EOF2_"

<html><head><title>Crypt</title></head>
<body bgcolor="#000000" text="#FFFFFF">
$user:$passwd<br><br>
crypt() another one?<br><br>
<form method="POST" action="$cgi_url">
<input type="hidden" name="action" value="doit">
Username <input type="text" name="user" value="" size="20">
Password <input type=text name="passwd" value="" size="20">
<p>
<input type=submit value=" crypt "> <input type=reset>
</form>
</body>
</html>
_EOF2_
;
exit;
}



Network Sockets

This is a basic code example to retrieve a webpage using raw tcp.
This will fetch the news backend from HNN - Hackernews.com
It isn't formatted, so you can get a good idea of what the raw HTTP Headers look like.
#!/usr/bin/perl
#
# Get the HNN Headlines

use Socket;
$port = 80;
$host = "www.hackernews.com";

print "Getting the HNN news Headlines...\n";

$iaddr = inet_aton($host) || die print("Failed to find host: $host");
$paddr = sockaddr_in($port, $iaddr) || die print("Something went wrong ... dieing...");
$proto = getprotobyname('tcp') || die print("Unable to get protocol");
socket(SOCK, PF_INET, SOCK_STREAM, $proto) || die print("Failed to open socket: $!");
connect(SOCK, $paddr) || die print("Unable to connect: $!");
$submit = "GET /headlines.html HTTP/1.0\n\n";
send(SOCK,$submit,0);
@thedata=;
#recv(SOCK, $thedata, 10000, undef);  #you can limit the bytes received with this
#       rather than the previous line
close (SOCK);

foreach $line(@thedata) {
print $line;
}
print "Done.\n";




 
[an error occurred while processing this directive] unique visits to this page since 01.28.2002 Last Modifed Tuesday, 04-Jan-2005 19:56:21 EST.
Remote
Antioffline.com
Siliconinc.net
Cryptome.org
Speedygrl.com
google.com
perlmonks.org unixhideout.com
freshports.org
daemonnews.org
         
Manage Account