📄 ch19.htm
字号:
directory and run under their user ID. This means that any files
the CGI program creates are owned by the same user. Damage caused
by any security bugs you may have introduced-via the CGI program-will
be limited to your own set of directories.
<P>
In addition to this security advantage, CGIwrap is also an excellent
debugging tool. When CGIwrap is installed, it is copied to <TT>cgiwrapd</TT>,
which can be used to view output of failing CGIs.
<P>
You can install CGIwrap by following these steps:
<OL>
<LI>Obtain the source from the <B>http://www.umr.edu/~cgiwrap/download.html</B>
Web page.
<LI>Ensure that you have root access.
<LI>Unpack and run the Configure script.
<LI>Type <B>make</B>.
<LI>With a user ID of root, copy the <TT>cgiwrap</TT>
executable to your server's <TT>cgi-bin</TT>
directory.
<LI>Make sure that <TT>cgiwrap</TT>
is owned by root and executable by all users by typing <B>chown
root cgiwrap; chmod 4755 cgiwrap</B>. The <TT>cgiwrap</TT>
executabe must also be set UID.
<LI>In order to gain the debugging advantages of CGIwrap, create
symbolic links to <TT>cgiwrap</TT>
called <TT>cgiwrapd</TT>, <TT>nph-cgiwrap</TT>,
and <TT>nph-cgiwrapd</TT>. The first
symbolic link can be created by typing <B>ln -s cgiwrap cgiwrapd</B>.
The others are created using similar commands.
</OL>
<P>
<p>
<CENTER>
<TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>
<TR><TD><B>Tip</B></TD></TR>
<TR><TD>
<BLOCKQUOTE>
You can find additional information at the <TT><B><FONT FACE="Courier">http://www.umr.edu/<B>~cgiwrap/install.html</B></FONT></B></TT> web site.
</BLOCKQUOTE>
</TD></TR>
</TABLE>
</CENTER>
<P>
<P>
CGIs that run using CGIwrap are stored in a <TT>cgi-bin</TT>
directory under an individual user's public Web directory and
called like this:
<BLOCKQUOTE>
<PRE>
http://servername/cgi-bin/cgiwrap/~userid/scriptname
</PRE>
</BLOCKQUOTE>
<P>
To debug a script run via cgiwrap, add the letter "d"
to <TT>cgiwrap</TT>:
<BLOCKQUOTE>
<PRE>
http://servername/cgi-bin/cgiwrapd/~userid/scriptname
</PRE>
</BLOCKQUOTE>
<P>
When you use CGIwrap to debug your CGI programs, quite a lot of
information will be displayed in the Web browser's window. For
example, if you called a CGI program with the following URL:
<BLOCKQUOTE>
<PRE>
http://www.engr.iupui.edu/cgi-bin/cgiwrapd/~dbewley/cookie-test.pl
</PRE>
</BLOCKQUOTE>
<P>
The output might look like this:
<BLOCKQUOTE>
<PRE>
Redirecting STDERR to STDOUT
Setting Limits (CPU)
Environment Variables:
QUERY_STRING: ''
PATH_INFO: '/~dbewley/cookie-test.pl'
REMOTE_HOST: 'x2s5p10.dialin.iupui.edu'
REMOTE_ADDR: '134.68.249.69'
SCRIPT_NAME: '/cgi-bin/cgiwrapd'
Trying to extract user/script from PATH_INFO
Extracted Data:
User: 'dbewley'
Script: 'cookie-test.pl'
Stripping user and script data from PATH_INFO env. var.
Adding user and script to SCRIPT_NAME env. var.
Modified Environment Variables:
PATH_INFO: ''
SCRIPT_NAME: '/cgi-bin/cgiwrapd/dbewley/cookie-test.pl'
Sanitize user name: 'dbewley'-'dbewley'
Sanitize script name: 'cookie-test.pl'-'cookie-test.pl'
Log Request
Opening log file.
Writing log entry.
Closing log file.
Done logging request.
User Data Retrieved:
UserName: 'dbewley'
UID: '8670'
GID: '200'
Directory: '/home/stu/d/dbewley'
UIDs/GIDs Changed To:
RUID: '8670'
EUID: '8670'
RGID: '200'
EGID: '200'
Current Directory: '/sparcus/users/dbewley/www/cgi-bin'
Results of stat:
File Owner: '8670'
File Group: '200'
Exec String: './cookie-test.pl'
Output of script follows:
=====================================================
Set-Cookie: user=dbewley; expires=Wednesday, 09-Nov-99 00:00:00 GMT;
path=/cgi-bin/; domain=.engr.iupui.edu;
Set-Cookie: flag=black; expires=Wednesday, 09-Nov-99 00:00:00 GMT; path=/
cgi-bin/; domain=.iupui.edu;
Set-Cookie: car=honda:accord:88:LXI:green; expires=Wednesday, 09-Nov-99
00:00:00 GMT; path=/cgi-bin/; domain=.engr.iupui.edu;
Content-type: text/html
Cookies:<BR>
flag = black<br>
car = honda:accord:88:LXI:green<br>
user = dbewley<br>
</PRE>
</BLOCKQUOTE>
<P>
This output can be invaluable if your script is dying because
of a syntax error before it can print an HTTP header to the browser.
<BR>
<p>
<CENTER>
<TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>
<TR><TD><B>Note</B></TD></TR>
<TR><TD>
<BLOCKQUOTE>
If you'd like a more in-depth description of CGI Security, visit these Web sites:</BLOCKQUOTE>
</TD></TR>
</TABLE>
</CENTER>
<P>
<BLOCKQUOTE>
<PRE>
http://www.csclub.uwaterloo.ca/u/mlvanbie/cgisec/# CGI Security Tutorial
http://www.umr.edu/</FONT><FONT SIZE=1 FACE="Courier">~</FONT><FONT SIZE=2 FACE="Courier">cgiwrap/ # CGIwrap Home Page
</PRE>
</BLOCKQUOTE>
<H2><A NAME="Cookies"><FONT SIZE=5 COLOR=#FF0000>
Cookies</FONT></A></H2>
<P>
Most Webmasters want to track the progress of a user from page
to page as they click about the site. Unfortunately, HTTP is a
<I>stateless</I> protocol. Stateless protocols have no memory;
they only understand the current command. This makes tracking
a visitor through a site difficult at best. A user could visit
a site, leave, and come back a day or a minute later, possibly
from a different IP address. The site maintainer has no way of
knowing if this is the same browser or not.
<P>
One answer to this dilemma is to use <I>cookies</I> in your CGI
programs. Cookies can provide a way to maintain information from
one HTTP request to the next-remember the coNCept of persistent
information?
<P>
A cookie is a small chunk of data, stored on the visitor's local
hard drive by the Web server. It can be used to track your path
through a Web site and develop a visitor's profile for marketing
or informational purposes. Cookies can also be used to hold information
like account numbers and purchase decisions so that shopping applications
can be created.
<H3><A NAME="CookieSecurity">
Cookie Security</A></H3>
<P>
There has been some controversy about whether cookies are secure.
Although the cookie mechanism provides a way for a Web server
to write data to your hard disk the limitations are very strict.
A client may only hold a maximum of 300 cookies at a time and
a single server may only give 20 cookies to it. Cookies can only
be 4 kilobytes each, iNCluding the name and data, so, at most,
a visitor's hard disk may have 1.2 megabytes of hard disk being
used to store cookies. In addition, cookie data may only be written
to one file, usually called <TT>cookies.txt</TT>.
<P>
During a browsing session, Netscape stores cookies in memory,
but when the browser is exited, cookies are written into a file
called <TT>cookies.txt</TT>. On the
Macintosh, the cookie jar is in a file called <TT>MagicCookie</TT>
in the prefereNCes folder. The cookie file contains plain text
as shown in Listing 19.3.
<H3><A NAME="HowAreCookiesCreatedandRead">
How Are Cookies Created and Read?</A></H3>
<P>
Cookies are set using a <TT>Set-cookie</TT>:
HTTP header with five possible fields separated with a semicolon
and a space. These fields are:
<UL>
<LI><B>cookie-name=cookie-value;</B>-name of the cookie and its
value. The name and the value combined must be less than 4 kilobytes
in length.
<LI><B>expiration=expiration-date;</B>-the date the cookie will
be deleted from the cookie file. You can delete a previously set
cookie ahead of schedule by creating a second cookie with the
same name, path, and domain, but with an expiration date in the
past.
<LI><B>path=cookie-path;</B>-combines with the domain name to
determine when a browser should show a cookie to the server.
<LI><B>domain=server-domain;</B>-used to determine when a browser
should show a cookie to the server. Usually, cookies are created
with the Web server's name without the <TT>www</TT>.
For example, <TT>.foo.net</TT> instead
of <TT>www.foo.net</TT>. Notice that
the leading period is retained.
<LI><B>secure</B>-ensures that the cookie will be sent back only
to the server when a secure HTTP connection has been established.
</UL>
<P>
When all of these elements are put together, they look like this:
<BLOCKQUOTE>
<PRE>
Set-Cookie: user_addr=ppp1.dialin.iupui.edu;
expires=Wednesday, 09-Nov-99 00:00:00 GMT; path=/cgi-bin/;
domain=.engr.iupui.edu; secure
</PRE>
</BLOCKQUOTE>
<P>
Listing 19.4 contains a program that both sets and read cookies.
First, it will create four cookies and then it will read those
cookies from the <TT>HTTP_COOKIE</TT>
environment variable. Inside the <TT>HTTP_COOKIE</TT>
environment variable, the cookies are delimited by a semicolon
and a space. The cookie fields are separated by commas, and the
name-value pairs are separated by equal signs. In order to use
cookies, you need to parse the <TT>HTTP_COOKIE</TT>
variable at three different levels.
<P>
<IMG SRC="pseudo.gif" tppabs="http://cheminf.nankai.edu.cn/~eb~/Perl%205%20By%20Example/pseudo.gif" BORDER=1 ALIGN=RIGHT><p>
<BLOCKQUOTE>
<I>Turn on the warning option.<BR>
Turn on the strict pragma.<BR>
Declare a variable to hold the expiration date and time of the
cookies.<BR>
Declare a variable to hold the domain name.<BR>
Declare a variable to hold the path name.<BR>
Set four cookies with different values.<BR>
Read those four cookies from the environment; place them into
</I><TT><I>%cookies</I></TT><I>.<BR>
Start the HTML Web page.<BR>
Display a text heading on the Web page.<BR>
Start an HTML table.<BR>
Display each cookie in a table row.<BR>
End the table.<BR>
End the Web page.<BR>
Define the </I><TT><I>setCookie()</I></TT><I>
fuNCtion.<BR>
Create local variables from the parameter array.<BR>
Send the </I><TT><I>Set-Cookie:</I></TT><I>
HTTP header to the Web browser.<BR>
Send the secure option only if requested.<BR>
End the header with a newline.<BR>
Define the </I><TT><I>getCookies()</I></TT><I>
fuNCtion.<BR>
Create a local hash to hold the cookies.<BR>
Iterate over an array created by splitting the </I><TT><I>HTTP_COOKIE</I></TT><I>
environment<BR>
variable based on the ";" character sequeNCe.<BR>
Split off the name of the cookie.<BR>
Create a hash entry with the cookie's name as the key and the
rest of the cookie as the entry's value.<BR>
Return the hash.</I>
</BLOCKQUOTE>
<HR>
<BLOCKQUOTE>
<B>Listing 19.4 19LST04.PL-How to Set and Retrieve
Cookies<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<PRE>
#!/usr/local/bin/perl -w
use strict;
my($expDate) = "Wednesday, 09-Nov-99 00:00:00 GMT";
my($theDomain) = ".engr.iupui.edu";
my($path) = "/cgi-bin/";
setCookie("user", "dbewley", $expDate, $path, $theDomain);
setCookie("user_addr", $ENV{'REMOTE_HOST'}, $expDate, $path, $theDomain)
if defined($ENV{'REMOTE_HOST'});
setCookie("flag", "black", $expDate, $path, ".iupui.edu");
setCookie("car", "honda:accord:88:LXI:green", $expDate, $path,
$theDomain);
my(%cookies) = getCookies();
print("Content-type: text/html\n\n");
print("<HTML>");
print("<HEAD><TITLE>The Cookie Display</TITLE></HEAD>");
print("<BODY>");
print("<H1>Cookies</H1>");
print("<TABLE BORDER=1 CELLPADDING=10>");
foreach (sort(keys(%cookies))) {
print("<TR><TD>$_</TD><TD>$cookies{$_}</TD></TR>");
}
print("</TABLE>");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -