Bugtraq mailing list archives

Re: SECURITY HOLE: FormMail


From: Andrew.Macpherson () bnr co uk (Andrew Macpherson)
Date: Thu, 3 Aug 1995 22:43:02 +0100


------- =_aaaaaaaaaa0
Content-Type: text/plain; charset="us-ascii"

Paul Phillips wrote:
| Here's the offending line:
|
| open (MAIL, "|$mailprog $FORM{'recipient'}") || die "Can't open $mailprog!\n";

------- =_aaaaaaaaaa0
Content-Type: text/plain; charset="us-ascii"

Just to be helpful, the way to do it more safely, without massive need for
checking is to build a complete mail message, including header, and hand that
to "sendmail -t" which then reads the recipient information out of the
constructed header.  [Sendmail should of course be an invocation of smail or
pp, not the BSD program of that name, given the history of problems that has
had]

... and since I'm sticking my neck out, here's an example script, please rip
to shreds :-)


------- =_aaaaaaaaaa0
Content-Type: text/plain; charset="us-ascii"
Content-Description: booking-form.cgi

#!/usr/bin/perl

print "Content-type: text/html\r\n\r\n";

if ( $ENV{REQUEST_METHOD} eq "POST") {

$\ = "\r\n";

# It's the POST method, so print content length and coded input from
# STDIN.  Then decode it and print again.

        $len = $ENV{CONTENT_LENGTH};
        $postinput = <STDIN> ;
        $postinput =~ s/\+/ /g ;
        @QUERY_LIST = split( /&/, $postinput);

        foreach $item (@QUERY_LIST) {
                ($param, $value) = split( /=/, $item);
                 $R{$param} = $value;
        }
        foreach $item (sort (keys %R)) {
                $R{$item} =~ s/%([\da-f]{1,2})/pack(C,hex($1))/eig;
                $R{$item} =~ s/\s+$/ /;
                $R{$item} =~ s/^\s+//;
        }
} else {
        print <<"EOX";

<HTML><TITLE>Wrong Submission Method</TITLE><BODY>
<H1>Installation Error</H1>

This script accepts input by the POST method.  Someone has invoked
it with some other method.  This means that either you are testing by hand,
congratulations, very wise; or that someone has set up a form to call it
using some other method.  If it was a form, then it was:
</P>

$ENV{"HTTP_REFERER"}
</P>
</BODY></HTML>
EOX
        exit ;
}

foreach $musthave ( "MAILTO", "SEMINAR", "NAME", "ADDR1", "ADDR2", "TELNO"){
        if ( length($R{ $musthave }) < 8 ) {
                print <<"EOE";

<HTML><TITLE>Please tell me more</TITLE><BODY>
<H1>Insufficient Information</H1>
<DL>
<DT>Either</DT><DD>There has been a problem sending your details to this
program.</DD>
<DT>Or</DT><DD>You have not filled in one of the fields I must have to be
able to take your booking this way.  If this is the case, would you please
go back to the form and make sure that you have entered your Name, address,
and telephone number, as the very minimum.  When you have made these
changes, please submit the form again.
</DD></DL></BODY></HTML>
EOE
                exit ;
        }
}

$copy = '';

$header =
"To: " . $R{"MAILTO"} . "\r\n" .
"Sender: nobody\r\nErrors-To: Postmaster@UNCONFIGURED\r\n" .
"Subject: " . ( $R{"SEMINAR"} ne '' ? $R{"SEMINAR"} : "WWW On Line booking" ) .
"\r\n" ;

if ( $R{"EMAIL"} ne '' && $R{"EMAIL"} =~ m/.*@.*/ ) {
        $em = $R{"EMAIL"};
        $header .= "Cc: ${em}\r\nReturn-Receipt-To: ${em}\r\n" ;
        $copy = "<H3>A copy has also been sent to your e-mail address</H3>" ;
} else {
        $em = $R{"NAME"} . " <nobody>";
}
$header .= "From: ${em}\r\nReply-To: ${em}\r\n\r\n\r\n" ;
$body =
$R{"SEMINAR"} . "\r\n" .
"=================================================================\r\n\r\n" .
"Name          " . $R{"NAME"} ."\r\n" .
"Organisation  " . $R{"ORG"} ."\r\n" .
"Address       " . $R{"ADDR1"} ."\r\n" .
"              " . $R{"ADDR2"} ."\r\n" .
"              " . $R{"ADDR3"} ."\r\n" .
"Telephone     " . $R{"TELNO"} ."\r\n" .
"Fax           " . $R{"FAXNO"} ."\r\n" .
"E-Mail        " . $R{"EMAIL"} ."\r\n\r\n" .
"=================================================================\r\n\r\n" .
"My User Group membership is " . $R{"GROUP"} ."\r\n\r\n" .
"Please Register me for the seminar, and invoice me for\r\n" .
$R{"BOOKING"} ."\r\n\r\n" .
$R{"VEGIE"} ."\r\n\r\n" .
"=================================================================\r\n"  .
$ENV{"HTTP_REFERER"} . "\r\n" .
$ENV{"HTTP_USER_AGENT"} . "\r\nFrom " .
$ENV{"REMOTE_HOST"} . "(" .  $ENV{"REMOTE_ADDR"} . ")\r\n" ;


open(MAIL, "|/usr/lib/sendmail -t");
print MAIL $header, $body;
close(MAIL);

if ( $? == 0 ) {
print <<"EOF";

<HTML><TITLE>Form Submitted</TITLE>
<BODY><H1>Thank You $R{"NAME"}</H1>
<H2>Your booking form has been submitted</H2>
$copy

Here is what was sent</P>

$body
</PRE></BODY></HTML>
EOF

} else {

print <<"EOF";

<HTML><TITLE>Request Failed</TITLE>
<BODY><H1>I'm sorry $R{"NAME"}</H1>
<H2>We could not submit your registration</H2>

Please try again later</P>
</BODY></HTML>
EOF

}

exit ;

------- =_aaaaaaaaaa0
Content-Type: text/plain; charset="us-ascii"

--
 Andrew.Macpherson.1248566 () bnr co uk    - or -    andrew () bnr ca
"Northern Telecom has committed to a 30% reduction in its use of paper
 by the year 2000."   No faxes, or printouts please, just e-mail.


------- =_aaaaaaaaaa0--



Current thread: