12.5 CGI Lint--A Debugging/Testing ToolCGI Lint greatly simplifies the process of testing and debugging CGI applications. Appendix E, Applications, Modules, Utilities, and Documentation, lists where you can get CGI Lint. Depending on the type of request (either GET or POST), either one or two auxiliary files are required by CGI Lint. The first is a configuration file, which should contain a list of the environment variables in the following format:
REQUEST_METHOD = GET QUERY_STRING = name=John Surge&company=ABC Corporation! HTTP_ACCEPT = image/gif, image/x-xbitmap, image/jpeg, */* SERVER_PROTOCOL = HTTP/1.0 REMOTE_ADDR = 198.198.198.198 SERVER_ROOT = /usr/local/bin/httpd_1.4.2 DOCUMENT_ROOT = /usr/local/bin/httpd_1.4.2/public GATEWAY_INTERFACE = CGI/1.1 SCRIPT_NAME = /cgi-bin/abc.pl SERVER_SOFTWARE = NCSA/1.4.2 REMOTE_HOST = gateway.cgi.com This format has an advantage over the previous one: You do not need to encode the query string. However, if you have either %, &, or = characters in the query string, you need to escape them by placing a "\" before them:
QUERY_STRING = name=Joe\=Joseph&company=JP \& Play&percentage=50\% Or you can just use the encoded values of %25, %26, and %3d to represent the "%," "&," and "=" characters, respectively. Now, you are ready to test out your CGI program:
% CGI_Lint get.cfg CGI Lint executes the script that is pointed to by the environment variables SCRIPT_NAME and SERVER_ROOT. In addition, you can use a data file to store query information. Here is an example:
% CGI_Lint form.cfg form.data The format for the data file should be:
name = Joe\=Joseph company = JP \& Play percentage = 50\% If you already have data stored in QUERY_STRING, CGI Lint will process the data from both sources. In the case of POST requests, all you have to do is change the REQUEST_METHOD to "POST" and run it in the same exact way as before:
% CGI_Lint form.cfg form.data In addition, you can test the multipart/form-data encoding scheme (see Appendix D, CGI Lite), which is a new addition to the Web. For multipart MIME data, you need to add the following line to the configuration file:
CONTENT_TYPE = multipart/form-data Normally, multipart data contains boundary strings between fields, but you do not have to go to the trouble of inserting the numerous multipart headers. CGI Lint takes care of all that for you. Now, here is the format for the data file:
name = Joe = Joseph company = JP & Play percentage = 50% review = */usr/shishir/rev.dat You would execute the script in the same way as you did all the others. CGI Lint reads through the fields and creates a multipart MIME body:
-----------------------------78198732381 Content-disposition: form-data; name="name" Joe = Joseph -----------------------------78198732381 Content-disposition: form-data; name="company" JP & Play -----------------------------78198732381 Content-disposition: form-data; name="percentage" 50% -----------------------------78198732381 Content-disposition: form-data; name="review"; filename="/usr/ shishir/rev.dat" . . (contents of the file /home/shishir/rev.dat) . . -----------------------------78198732381-- One thing to note here is the last line of the data file. The asterisk instructs the tool to include the information stored in the file /usr/shishir/review.dat. That is one of the powerful features of multipart messages: it allows users to upload files to the server. In addition to simulating the server data streams, CGI Lint also checks a number of attributes and properties before running the script. CGI Lint in ActionLet's take a simple CGI program and run it through CGI Lint, and see what happens. Here is the program-it should be familiar to you, as it was introduced at the end of Chapter 7, Advanced Form Applications:
#!/usr/local/bin/perl &parse_form_data(*simple); $user = $simple{'user'}; print "Content-type: text/plain", "\n\n"; print "Here are the results of your query: ", "\n"; print `/usr/ucb/finger $user`; print "\n"; exit (0); This program outputs finger information about the specified user. Here is the form that is associated with the program:
<FORM ACTION="/cgi-bin/finger.pl" METHOD="POST"> <INPUT TYPE="text" NAME="user" SIZE=40> <INPUT TYPE="submit" VALUE="Get Information"> </FORM> Now, let's create the configuration and data files, to be used with CGI Lint. The configuration file must contain the following lines:
REQUEST_METHOD = POST SERVER_ROOT = /usr/local/bin/httpd_1.4.2 SCRIPT_NAME = /cgi-bin/finger.pl Since the form passes the information to the program using POST, we need to create a data file to hold the post data. It needs to consist of only one line:
user = shishir This is equivalent to the user entering "shishir" in the user field in the form. That is all that needs to be done. Here is how you would execute CGI Lint (assuming that the configuration file is called finger.cfg, and the data file is called finger.dat):
% CGI_Lint finger.cfg finger.dat CGI Lint will output the following information:
While looking at your Perl script for possible security holes and "open" commands, I came across the following statements that *might* constitute a security breach: ================================================================================ Check the *backtics* on line: print `/usr/ucb/finger $user`; Variable(s) *may* not be secure! ================================================================================ It looks as though your script has no bugs (at least, on the surface), so here is the output you have been waiting for: ================================================================================ Here are the results of your query: <BR><HR> Login name: shishir In real life: Shishir Gundavaram Directory: /home/shishir Shell: /usr/local/bin/tcsh On since Oct 26 23:11:27 on ttyp0 from nmrc.bu.edu Mail last read Mon Oct 27 00:03:54 1995 No Plan. <HR> ================================================================================ It will display the output generated by the CGI program. It also outputs various other information, including possible security holes. Here is a list of the exact informational messages that CGI Lint outputs:
|
|