📄 ch03.htm
字号:
print "\tCurrent users in $opt:\n";
$users = new HTTPD::UserAdmin(DBType => "Text",
Path => $path, Locking => 0, Server => "apache");
#@users = $users->list;
foreach $user (sort($users->list)){
print "\t\t$user : ";
print $users->password($user),"\n";
}
}
}
print "\tLimit: @{$V->{Directory}{$dir}{LIMIT}{METHODS}}\n";
while(($key,$val) = each %{$V->{Directory}{$dir}{LIMIT}{OPTIONS}}) {
print "\t\t$key = @{$val}\n";
}
print "\n";
}
# rudimentary permissions checking
$webuser = (getpwnam($V->user))[2];
opendir(ROOT,$V->server_root);
@files = grep(!/\.\.?/,readdir(ROOT));
closedir(ROOT);
foreach $f (@files){
@s = Stat($V->server_root."/$f");
if($s[$ST_UID] == $webuser){
print "Warning: ",$V->server_root,"/$f is owned by ",
$V->user,"\n\n";
}
if($f eq "httpd"){
if(($s[$ST_MODE] != 0100700) or ($s[$ST_UID] != 0)){
print "\tWarning: ",$V->server_root,"/httpd may have\n";
print "\tpermission problems. Recommend root ownership\n";
print "\tand readable, writable and executable only by\n";
print "\troot user\n";
}
}
}
</FONT></PRE>
<P>We get a fairly nice report back that looks like this:</P>
<PRE><FONT COLOR="#0066FF">Userid: nobody
Group: nogroup
Administrator is: wmiddlet@adobe.com
Running at port: 80
Access filename: .privaccess
User Directory: public_html
Global Types: text/html .shtml
Options for Directory: /usr/local/etc/httpd/cgi-bin
Options : None
AllowOverride : None
Limit:
Options for Directory: /usr/local/etc/httpd/htdocs/test1
Options : None
AllowOverride : None
Limit: GET POST
require = valid-user
Options for Directory: /usr/local/etc/httpd/htdocs
PerlHandler : main::handler
AuthUserFile : /usr/local/etc/httpd/conf/.htpasswd
Current users in AuthUserFile:
bmiddlet : ztTO6y2K.3qLE
bozo : 0Euk1WMWyXRgg
josie : _LhTDVY/y6tPo
AddType : text/html .shtml
AuthName : PasswordAdmin
Options : Indexes SymLinksIfOwnerMatch IncludesNOEXEC
AuthType : Basic
AllowOverride : AuthConfig FileInfo Indexes Limit
Limit: GET
deny = from .bozo.com
order = mutual-failure
allow = from .metronet.com
</FONT></PRE>
<P>Of course, if your user database gets very large, then this script may produce
more output than you want to see. The idea from the beginning has been that this
script would run automatically via cron, having its output compared to the expected
output, possibly from the day before, then sending on only the differences for your
inspection.
<CENTER>
<H3><A NAME="Heading16"></A><FONT COLOR="#000077">CGI Security</FONT></H3>
</CENTER>
<P>If you use CGI scripts at all in your Web server, you'll need to take special
care to make sure that they're safe. There have been a number of break-ins and other
security violations due to incorrectly configured or carelessly written CGI programs.
It will pay to be completely familiar with all of the issues and precautions regarding
using the CGI.
<CENTER>
<H4><A NAME="Heading17"></A><FONT COLOR="#000077">General Considerations: Dos and
Donts</FONT></H4>
</CENTER>
<P>Because the CGI modules are introduced later in this book, you will not learn
how they specifically deal with the potential security holes at this time. Most security
holes introduced through the use of CGI scripts are unintentional; the following
section discusses some of the most pop- ular ones. <B><TT>Never Trust Anything Sent
As Input</TT></B> This is the first rule of safe CGI programming. Just because the
server is running as the <TT>nobody</TT> user doesn't mean that malicious activities
can't be carried out. If your input data is being processed in any way, even just
writing it onto a file, the potential for an attack exists. The following list illustrates
some of the most important considerations when creating CGI programs and handling
input to forms: <BR>
<TABLE BORDER="0">
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT" VALIGN="TOP">Variable Length</TD>
<TD ALIGN="LEFT">A form may prompt for a variable specifying a MAXLENGTH, but the sender may potentially
send a form variable thousands of bytes long. This problem was, in fact, a CERT Announcement
against an early version of the NCSA httpd. Be sure that you're not running httpd
with a version number earlier than 1.4 to avoid the hole this created. Also make
sure that your script itself can handle such a long submission properly.</TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT"><FONT COLOR="#000000">Shell MetaCharacters</FONT></TD>
<TD ALIGN="LEFT"><FONT COLOR="#000000">The input from a form could potentially include shell meta
characters or other special characters or commands that could get you in trouble.</FONT></TD>
</TR>
</TABLE>
<CENTER>
<H3>
<HR WIDTH="83%">
<FONT COLOR="#0066FF"><BR>
</FONT><FONT COLOR="#000077">CAUTION:</FONT></H3>
</CENTER>
<BLOCKQUOTE>
<P>Never, under any circumstances, pass user input to the shell in raw form; in fact,
you shouldn't have to ever invoke a shell process at all if you're doing things right.
If you use the CGI and Mail modules to process the form and perform the desired action(s),
this is handled for you automatically. Even so, it never hurts to apply your own
standard to the returned values from the CGI parsing process just to be sure.
</BLOCKQUOTE>
<P>
<HR WIDTH="83%">
<TABLE BORDER="0">
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT">Selection Lists/Variables</TD>
<TD ALIGN="LEFT">The value input for some selection list item, or any variable for that matter, may
not be among the ones that you've specified. If you have a default action, make it
do nothing or warn for any unexpected value.</TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT" VALIGN="TOP"><FONT COLOR="#000000">Hidden Variables</FONT></TD>
<TD ALIGN="LEFT"><FONT COLOR="#000000">Don't assume that just because you define a variable to be
hidden in your form, it can't be seen by any means. The same goes for Netscape cookies:
The malicious client could send something to you as a hidden variable or cookie that
you didn't give the client in the first place.</FONT></TD>
</TR>
</TABLE>
<BLOCKQUOTE>
<PRE></PRE>
</BLOCKQUOTE>
<P>In general, as has been mentioned, invoking a shell with any form input should
be avoided. It is very easy to do the right thing with user input when you use the
CGI modules to process the form. Alas, there will always be the need for the quick
hack, sometimes due to urgency or immediate need for results, and other times due
simply to laziness. A quick review of the no-no's is thus in order:
<OL>
<LI>Never invoke the shell directly. Perl provides several techniques for getting
past the shell directly to the desired program, and these should be utilized. For
instance, you could invoke sendmail by using the following:
<PRE><FONT COLOR="#0066FF">system("/usr/lib/sendmail -t $address < $input_file");
</FONT></PRE>
<P>But doing it this way is a big mistake, especially when the <TT>$</TT>address
and/or the <TT>$</TT>input_file variables may come from the form itself. It's much
better to invoke sendmail like this:</P>
<PRE><FONT COLOR="#0066FF">open(SENDMAIL, "/usr/lib/sendmail -t|");
</FONT></PRE>
<P>Then print directly on the <TT>SENDMAIL</TT> pipe, first the header, followed
by the body of the mail, and close it. However, it can't be stressed enough that
even this could get you in trouble. You should always use the <TT>Mail::Send</TT>
module's methods to send mail. Another technique for getting past the shell in <TT>system()</TT>
is to use the somewhat obscure technique of quoting each parameter to the command
line:</P>
<PRE><FONT COLOR="#0066FF">system "/usr/bin/sort", "$input_file";
</FONT></PRE>
<P>This syntax invokes the <TT>sort</TT> command directly instead of passing the
arguments through the shell. Note how we explicitly specified the full path to the
<TT>sort</TT> command. Never rely on the <TT>$PATH</TT> variable to figure out which
command you really mean. This is how Trojan horses get inside the gates. Also, don't
forget that <TT>system()</TT> isn't the only way to invoke a shell with Perl. There
are also the backtick operators, <TT>fork()</TT>, <TT>exec()</TT>, and <TT>pipe()</TT>,
and even <TT>glob()</TT> and implicit <TT>glob</TT> via <TT><'command'></TT>.
Be very careful with quoted <TT>eval""</TT> statements, as well.
<OL>
<P>
</OL>
<LI>Always turn tainting on with the <TT>-T</TT> option to Perl. This option automatically
renders arbitrary input as "tainted" and unusable in subprocess invocations
until it is untainted. Of course, it's quite easy to untaint variables, but if you
turn on <TT>-T</TT> in the shebang line of your Perl script, you might catch yourself
in a moment of weakness when you've forgotten to escape some arbitrary input.<BR>
<BR>
<LI>If you insist on parsing your own input, there are basically two policies, the
first being that anything not permitted is forbidden. The regular expression
<PRE><FONT COLOR="#0066FF">$address =~ /^[\w@\.\-]+$/;
</FONT></PRE>
<P>allows only a specific class of characters, which should match an e-mail address.
If, when your <TT>$address</TT> variable doesn't match this regexp, your programs
errors, you're enforcing this policy. The other alternative is to permit anything
that isn't forbidden. If, for instance, you check your <TT>$address</TT> for any
shell meta-characters with the following regexp:</P>
<PRE><FONT COLOR="#0066FF">$address =~ /([;<>\*\|'&\$!#\(\)\[\]\{\}:'"])/;
</FONT></PRE>
<P>and then allow anything that doesn't match, you're enforcing the less-restrictive
policy, specifying only what is unsafe. As you might expect, the former is preferred.
And again, using the CGI modules handles this for you.
<LI>Finally, always be sure to check and double-check before allowing arbitrary input
to be used for a pathname. Be especially vigilant for the old <TT>`..'</TT> operator,
which can be used to access files down from the htdocs directory and possibly into
the /etc directory, where the passwd file lives.
<P><BR>
Using the various CGI modules to create and especially process your form input will
help you to avoid these traps. You have additional power to prevent attacks and limit
the capabilities of the client using several other powerful Perl modules that aren't
discussed elsewhere in this book. Let's take a look at these now.
</OL>
<CENTER>
<H4><A NAME="Heading19"></A><FONT COLOR="#000077">Tools for Executing CGI Safely</FONT></H4>
</CENTER>
<P>If you're using Perl as your CGI scripting mechanism, there are a number of new
tools and modules you can use to assure that your CGI scripts operate correctly and
safely. These modules are consistently maintained and updated, and the authors are
fully aware of all of the potential problems that face the Webmaster when introducing
the CGI risk to his or her Web. We'll be introducing these tools and modules in Chapter
5, "Putting It All Together."
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -