####################################################### # # display-notes related to Intro to Perl, Class 9 # ####################################################### # last modified: 5-9-03, pre-class # today's topic - a TINY taste of CGI... #------------------------------------------------------------------- #------------------------------------------------------------------- # CAVEATS!! * any time your web server fires off any general-purpose interpreter --- such as /usr/bin/perl, php, etc. --- it is a potential security hole. * IF a rogue outside can somehow insert their own commands instead of those in the script, those rogue commands would be run by that interpreter with the native script's permissions; * a custom Perl script that you write is possibly less unsafe than a downloaded popular one (such as formmail.pl, known to have a security flaw), that some hackers have deconstructed and studied byte-by-byte; * (there ARE robots that scan the Internet looking for this formmail.pl, for example, to try to break into systems by taking advantage of this flaw;) * you are less unsafe with later versions of Perl than with earlier versions of Perl; AND, * you are in even better shape if you use a version of Linux that is supported by a programmer community that swiftly responds to security problems and issues security updates that you can then download and install in literally one command; * (note: a compiled binary is much more safe than source code; a compiled Perl executable would be safer than a Perl script. I *think* I read about such work in progress...) * source for the above: random security expert than I cornered and coerced until he fed me the above information... * look into taint-checking as well... * a good site for general security information: www.cert.org #----------------------------------------------------------------------- #----------------------------------------------------------------------- * CGI: common gateway interface * special directory on your system that contains all the scripts and executable files that your web server is permitted to run at the request of an external user; * (sort of like anonymous ftp --- external user can only run what's in that subdirectory;) * these CGI scripts and executable files might "...process the results of a form, perform a search, produce dynamic web content, or count the number of accesses to a web page." * (the above quote is from "Learning Perl", p. 294 --- which only has about 3 pages on CGI, not wanting to give the reader "just enough knowledge to be dangerous", and saying that "a proper discussion of the problems inherent in CGI programming would probably add at least 50% to the size (and cost) of this book" (p. 295). Which makes me feel *really* good about today's very brief intro. So beware.) * (they note that there are many good books on this, including "CGI Programming with Perl", Scott Guelich, et al, O'Reilly, and "Network Programming with Perl", Lincoln Stein, Addison-Wesley (p. 296)) #------------------------------------------------------------------------- # how can you experiment with CGI programming here on campus? * note: don't expect to be able to do this from all service providers... * you may know the following already, but in case you don't: * In your account on sorrel, you may know that you can create a directory named public_html. If you make this directory world-executable --- chmod 711 public_html ...then html files you put in this directory (that are world-readable --- chmod 644 my_web_page.html )...can be viewed on a web browser using the URL: http://www.humboldt.edu/~your_user_name/my_web_page.html (that is, if your username on sorrel is abc13 and you created a page cool_stuff.html, its URL would be: http://www.humboldt.edu/~abc13/cool_stuff.html) * and if you create a page with the *specific* name index.html, then that page will be displayed automatically for the URL http://www.humboldt.edu/~your_user_name * So, you may know that already. * What you may not know is that you are permitted to create a directory named cgi-bin within your public_html directory: # assume you are in public_html mkdir cgi-bin chmod 711 cgi-bin # make it world-executable, too * Within this directory, you, too, can place scripts and executable files that web server sorrel is permitted to run at the request of an external user, to process the results of a form, perform a search, produce dynamic web contents, count the number of accesses to a web page, etc.; #----------------------------------------------------------------------- # sketchy examples * (thanks to Professor Burroughs, who kindly provided me with CIS 318 examples to kluge from.) * minor aside-but-related #1: in our file I/O discussion on Monday, I didn't mention that Perl has a read command, too. * it can accept an input filehandle as its first argument, and a string to be read into as its second argument, and how many characters to read in as its third argument?! read STDIN, $input, 3; * a short example is in class9_01_read; * we'll see this in some of today's CGI scripts. #----------------------------------------------------------------- # what goes in the HTML page to CALL your cgi script? * it looks like the following is one way, assuming that your username is abc13:
* consider class9_02.pl in cgi-bin, class9_02.html in public_html: # class9_02.pl #!/usr/bin/perl -w open HTML_INPUT, "< class9_02_html_contents" or die "Cannot open class9_02_html: $!"; # will this post the current contents of this file HTML_INPUT? print "Content-type: text/html", "\n\n"; while () { $next_line = $_; print $next_line; } close HTML_INPUT; # key part from class9_02.html
* in this example, the perl script class9_02.pl is executed when the the button "Push me" is pushed; it simply spews back HTML to display a different web page. * note that, BEFORE you start printing the HTML, you apparently need to print: print "Content-type: text/html", "\n\n"; ....to tell the web browser what's coming, so it will know how to handle it. #----------------------------------------------------------------------- # hash ENV * hash ENV evidently can access various environment variables; * consider this perl CGI script, class9_03.pl, from Prof. Burroughs: #!/usr/bin/perl # from A. Burroughs print "Content-type: text/html", "\n\n"; print "", "\n"; print "About this Server", "\n"; print "

About this Server

", "\n"; print "
";
print "Server Name:      ", $ENV{'SERVER_NAME'}, "
", "\n"; print "Running on Port: ", $ENV{'SERVER_PORT'}, "
", "\n"; print "Server Software: ", $ENV{'SERVER_SOFTWARE'}, "
", "\n"; print "Server Protocol: ", $ENV{'SERVER_PROTOCOL'}, "
", "\n"; print "CGI Revision: ", $ENV{'GATEWAY_INTERFACE'}, "
", "\n"; print "
", "\n"; print "", "\n"; exit (0); * apparently, hash ENV has information such as the server name, server port, server software, server protocol, and gateway interface; and there's more, too. Maybe too much --- if you try this to different servers, don't be surprised if some won't give you all of this information. #--------------------------------------------------------------------------- # getting info from the HTML page - part 1 - some simple HTML form info * you can set up a textfield within an HTML form by using: | a text field... | | how form info will be identified when sent | | to Perl script v v * a password field is like a textfield, except it will not show what is typed on the screen (so someone looking over one's shoulder cannot see the password being typed): * something like this will send the contents of all textfields to your Perl CGI script when you push the button labeled "Send it": * something like this will clear all of the textfields when you push the button labeled "Clear": * this appears to let you insert some horizontal space "between" items in a form... * remember to "end" your form with an end-of-form tag: #----------------------------------------------------------------------- # getting info from the HTML page - part 2 - the Perl CGI script side * evidently, a string is sent to Perl with the contents of fields in an HTML form when a submit button is pressed; its size is evidently can evidently be determined using $ENV{"CONTENT_LENGTH"}. So, the following seems to be able to read the information from the form: read STDIN, $info_string, $ENV{"CONTENT_LENGTH"}; * you can then do what you wish to the string --- in class9_05.pl, I append it to a file, so I can look at it! 8-) Then I send back a confirmation page. * see class9_05.pl, class9_05.html, class9_05_sent_info * note the string sent to class9_05_sent_info --- one might look like this: desired_label=Sharon+M.+Tuttle&passwd_label=nuthin * & appears to be a delimiter between the values of the different fields * blanks appear to be replaced by +'s for transport across the network * NON-letters and non-digits will come out looking different you expect!! (because these are really sent as unicode characters...) #--------------------------------------------------------------------- # slicing and dicing form fields * gee, Perl would't be any good at grabbing out the information from $info_string, would it? 8-) * want a hash of fields and their values? * see class9_06.pl, class9_06.html, class9_06_sent_info # first, change each = to & ? (want to be split into separate values, # I think) $info_string =~ s/=/&/g; # ...and change each + back to a blank now --- they won't be # accidentally split on now, with the &'s in place; $info_string =~ s/\+/ /g; print HTML_INFO "$info_string\n"; # split on & @fields_and_values = split /&/, $info_string; print HTML_INFO "@fields_and_values\n"; # store fields and their values into hash %field_value_hash = @fields_and_values; @ck = %field_value_hash; print HTML_INFO "@ck\n"; print HTML_INFO "\nHere are fields and their values:\n"; foreach $field (sort keys %field_value_hash) { print HTML_INFO "$field => $field_value_hash{$field}\n"; } close HTML_INFO; # try to send back a confirmation page print "Content-type: text/html", "\n\n"; print "\n"; print "Confirmation\n"; print "

Confirmation

\n"; print "
\n"; print "Information transferred?
"; print "name given was: ", $field_value_hash{"desired_label"}, "\n"; print "\n"; print "\n"; # end of class9_06.pl #--------------------------------------------------------------------- # calling a Perl script directly from the web?! * there are problems with class9_04.pl, although CAN call it directly from web?! * call it directly from a browser using: http://sorrel.humboldt.edu/cgi-bin/cgiwrap/st10/class9_04.pl # end of 180class9_notes.txt