Introduction to PERL
Part 4
(1) Working with Files (2)CGI Security
Working with Files
• So far programs cannot store data values inbetween times when they are started.
– Working with files enable programs to store data, which can then be used at some future time.
• Will describe ways to work with files in CGI/Perl programs, including
– opening files, – closing files, – and reading from and writing to files
Using the open() Function
• Use to connect a program to a physical file on a Web server. It has the following format:
open ( INFILE, "mydata.txt" ); Filehandle: A name used to refer to the file in your program. Filename: The name of the file on the web server.
– file handle - Starts with a letter or number—not with ―$‖, ―@‖, or ―%‖. (Specify in all capital letters. (By Perl convention.)
– filename - name of file to connect to. If resides in the same file system directory then just specify the filename (and not the entire full file path).
More On open() function
• open() returns 1 (true) when it successfully opens
and returns 0 (false) when this attempt fails. • A common way to use open()
$infile = “mydata.txt”;
open (INFILE, $infile ) || die “Cannot open $infile : $!”;
Connect to mydata.txt.
Execute die only when open fails
Output system message
Using the File Handle to Read Files
• Use the file handle to refer to the file once opened • Combine with the file handle with the file input operator (―<>‖) to read a file into your program. • For example, the following opens a file and then outputs the first and third lines of the file. – Program uses indata.txt containing:
Apples are red Bananas are yellow Carrots are orange Dates are brown
Example Program
$infile="mydata.txt"; open (INFILE, $infile ) || die "Cannot open $infile: $!"; @infile = ; print $infile[0]; print $infile[2]; close (INFILE);
• Then the output of this program would be
Apples are red Carrots are orange
Reading One Line At a Time:
• Reading a very large file into the list variable @infile consumes a lot of computer memory.
– Better is to read one line at a time. For example the following would print each line of the input file.
$infile=”mydata.txt”; open (INFILE, $infile ) || die “Cannot open $infile: $!”; while ( ) { Automatically set $inline=$_; to the next input print $inline; line. } close (INFILE);
Example Program
1. #!/usr/bin/perl 2. use CGI ':standard'; 3. use CGI::Carp "fatalsToBrowser"; 4. print header, start_html('Inventory List'); 5. $infile="infile.txt"; 6. open (INFILE, $infile ) || die "Cannot open $infile: $!"; 7. while ( ) { 8. $inline=$_; 9. ($ptno, $ptname, $num, $price ) = split ( /:/, $inline ); 10. print "We have $num $ptname ($ptno). "; 11. print "The cost is $price dollars.", br; 12. } 13. close (INFILE); 14. print end_html
Output ...
Writing to Files
• write-only-append: allows you to write and append data to the end of a file.
– If the file exists, it will write to the end of the existing file. Otherwise will create it. – To specify this mode, use >> before the filename in the open() function.
open(OFILE, “>>myfile.txt”) || die “Cannot open: $!”;
• Example way to write to
print OFILE “My program was here”;
Reading and Writing Files
1. #!/usr/bin/perl 2. use CGI ':standard'; 3. use CGI::Carp "fatalsToBrowser"; 4. print header, start_html('My Page'); 5. print '', "WELCOME TO MY SITE "; 6. $ct = &counter(); 7. print br, '', "You Are Visitor $ct "; 8. print end_html; 9. sub counter { 10. $ctfile="/home/perlpgm/logfiles/counter.txt"; 11. open (CTFILE, "<" . $ctfile ) || die "Cannot open $infile: $!"; 12. @inline = ; 13. $count=$inline[0] + 1; 14. close (CTFILE); 15. open (CTFILE, ">$ctfile" ) || die "Cannot open $infile: $!"; 16. flock (CTFILE, 2); 17. print CTFILE "$count"; 18. close (CTFILE); 19. return $count; 20. }
Output ...
Example Guest Book
1.#!/usr/bin/perl 2. use CGI ':standard'; 3. use CGI::Carp "fatalsToBrowser"; 4. print header, start_html('Logger'); 5. $comments = param('ucomments'); 6. $logfile=">>/inetpub/wwwroot/logfiles/mydata.txt"; 7. open (OUTFILE, $logfile ) || die "Cannot open $infile: $!"; 8. $remrefer=$ENV{'HTTP_REFERER'}; 9. ( $sec, $min, $hr, $Day, $mon, $year ) = localtime(time); 10. $year=$year+1900; 11. $mon = $mon + 1; 12. print OUTFILE "$mon/$Day/$year:$hr:$min:$remrefer:$comments\n"; 13. print 'Just Logged:', br,"$mon/$Day/$year:$remrefer:$comments"; 14. close (INFILE); 15. print end_html;
Cookies
• Cookies provide a way for Web server applications to store small pieces of data on the end user’s machine. • Cookies can be easily refused by the end user and therefore cannot be relied upon to always be available to the CGI/Perl program. • Data set by cookies can be available for long periods of time, even when the end user leaves the site and comes back months later.
Setting a Cookie
• Can request that a browser cookie be saved in memory (deleted when user exits browser)or onto disk (retained until an expiration date). • Syntax of an in memory cookie:
The cookie's name and value print "Set-Cookie: cust_name=Dave\n"; Directs the browser to establish a cookie
• Must output before the MIME Content-type line.
Setting Cookie Expiration Date
• When need to retain a cookie between browser sessions, need to set expiration date
The cookie's name and value print "Set-Cookie: cust_name=Dave; expires=04-Jul-2003 00:00:0 GMT\n"; Directs the browser to establish a cookie The date and time the data should be removed
• Again this line must be output before the MIME Content-type line
A Sample Program That Sets A Cookie
1. #!/usr/bin/perl 2. use CGI ':standard'; 3. $name=param('name'); 4. $prefers=param('prefers'); 5. print "Set-Cookie: cust_name=$name; expires=04-Jul-2003 00:00:0 GMT\n"; 6. print "Set-Cookie: cust_prefer=$prefers; expires=04-Jul-2003 00:00:0 GMT\n"; 7. 8. print header, start_html('set cookie'); 9. print br, "Thanks $name Lets now look at $prefers . . . "; 10. 11. print end_html;
Output ...
Example Cookie Reading Program
1. #!/usr/bin/perl 2. use CGI ':standard'; 3. print header, start_html("Welcome "); 4. $cust_name=cookie( 'cust_name'); 5. $prefers=cookie('cust_prefer'); 6. print ''; 7. if ($cust_name) { 8. print "Welcome back $cust_name to our humble hardware site."; 9. } else { 10. print ' '; 11. print 'Welcome to our humble hardware site.'; 12. } 13. if ( $prefers eq "hand tools" ) { 14. print br,'We have hammers on sale for 5 dollars!'; 15. } elsif ( $prefers eq "power tools" ){ 16. print br, 'We have power drills on sale for 25 dollars!'; 17. } else { 18. print br, ''; 19. print ' We have drills and hammers on special today!'; 20. } 21. print "", end_html;
Output ...
Hidden Fields
• Hidden fields are HTML form fields that you can use to set name/value CGI variables without displaying them on a form. • Hidden fields provide a method to manage user sessions by maintaining the state of each session. – Hidden fields are not a secure method to keep data. • You can create sophisticated multiple-screen applications, such as shopping carts and surveys, by using hidden fields.
CGI Security
• What about web server security?
– Letting anyone run programs on your server can be risky – Be sure to set up your web server properly
• What about CGI script security?
– Disallow risky operations like pointer arithmetic, array access without bounds checking, etc. – Perl is designed to prevent such problems – But must be aware of outside execution (``)
• Check perldoc perlsec for security information
A Bad Example
1. 2. 3. 4. 5. #!/usr/athena/bin/perl # A REALLY BAD IDEA! print "who is here? "; $user = <>; $output = `You are $user`; print "$output\n";
• It could become: Who is here? rjbarbal Who is here? ; rm -rf /
CGI Taint Mode
1. #!/usr/athena/bin/perl -T 2. use strict; #important 3. use warnings; #important 4. # Prompt and get user input 5. print ―Who are you? "; 6. my $user = <>; 7. # Untaint user input 8. if ($user =~ /^(\w*)$/) { 9. $user = $1; 10. } else { die "Illegal username"; 11. } # Make path safe 12. $ENV{'PATH'} = '/bin:/usr/bin:/usr/athena/bin/'; 13. # Command is now safe my 14. $output = `You are $user`; 15. print "$output\n";
More Tainted CGI
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. #!/usr/athena/bin/perl -T use strict; use warnings; use CGI qw( :standard ); # Make path safe $ENV{'PATH'} = '/bin:/usr/bin:/usr/athena/bin/'; print header(), start_html('A Simple Example'), h1('A Simple Example'), start_form(), ―Who are you? ", textfield('user'), submit(), end_form(), hr(); # Get user input my $user = param('name'); if ($user) { # Untaint user input if ($user =~ /^(\w*)$/) { $user = $1; # Command is now safe my $output = `finger $user`; print pre("$output\n"), hr(); } else { # User input is unsafe print p("Invalid username. Please try again."); }} print end_html();
Web Sites
• • • • • • • • www.perl.com, The Source for Perl www.perl.org, Perl Mongers, the Perl advocacy people learn.perl.org, For people learning Perl jobs.perl.org, Employers seeking Perl programmers use.perl.org, Perl community news and discussion www.perldoc.com, Perl documentation www.cpan.org, Comprehensive Perl Archive Network www.tpj.com, The Perl Journal, a magazine
Documentation
• Commands:
– man perl – perldoc
• On the web:
– http://www.perl.com/CPAN/ – http://www.perldoc.com/
The End