[2077] in bugtraq
Re: SECURITY HOLE: FormMail
daemon@ATHENA.MIT.EDU (Andrew Macpherson)
Fri Aug 4 18:26:19 1995
Date: Thu, 3 Aug 1995 22:43:02 +0100
Reply-To: Bugtraq List <BUGTRAQ@CRIMELAB.COM>
From: Andrew Macpherson <Andrew.Macpherson@bnr.co.uk>
X-To: Bugtraq List <BUGTRAQ@CRIMELAB.COM>
To: Multiple recipients of list BUGTRAQ <BUGTRAQ@CRIMELAB.COM>
In-Reply-To: Message from Paul Phillips on Wed, 02 Aug 95 21:28:43 -0800.
------- =_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>
<P>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>
<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
<P>Here is what was sent</P>
<PRE>
$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>
<P>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--