[thelist] formmail "bad referrer" error, with no apparent cause?
Keith
cache at dowebs.com
Sat Dec 8 01:23:27 CST 2001
> Can anyone give me a clue as to what might be causing one user to get
> a bad referrer error on a form? The cgi script is a slight
> modification of Matt's FormMail. It hasn't been changed for 6 months,
> it had been working normally, and works when I test it now. The
> referrer that the script error handler reported as being in error is
> one of the referrers in the referrer array.
Hi Heather,
It could be a number of things. First thing to do, find out what
referrer formmail is receiving. Place the following on line 34 (just
above the @referrer = line) and have your user try it (you might want
to create a copy with a different name while testing because this
will kill the script)
print "Content-type: text/html\n\n";
print "referrer is $ENV{'HTTP_REFERER'}";
exit;
That way the script will fail and report back the referrer that it
received. Once you've done that the problem should be obvious, or
at least you'll have a starting point. I'd look for a Perl metacharacter
in the referrer, or no referrer at all (depending on your "slight
modification").
It's a weird coincidence that you posted a message about formmail.
Just the other day I was reviewing our server error logs and saw
that 14 times in the last month different domains on our servers
were getting "file not found: cgi-bin/formmail.pl" errors. We've never
allowed a cgi-bin on our servers or allowed formmail. Those errors
were coming from a robot scanning our cornor of the web, looking
for a spam relay. Matt Wright's FormMail.pl is the most widely used
spam relay on the web. And since you are relying on the referrer
array, your installation IS a spam relay.
A lazy spammer can trick FormMail into not even using the
@referrer array and substitute his victim's email address for the
recipient. But enterprising spammers (ones who come looking for
you with robots) will send a fake referrer, making FormMail think the
form is coming from a referrer in your @referrer array, again
substituting his victim's email address for the recipient. These tricks
are well documented, easily available, and widely used by
professional spammers to turn your FormMail into a spam relay
server.
In addition to being a spam relay FormMail is a portal for a "denial
of service attack". Since it's easy to automate using FormMail to
hijack your server's email program, it's easy to throw a million
emails through it, bogging your server down or crashing it.
You may think that FormMail's vulnerability is not your problem. In a
sense you're right, it's Matt's problem, one he's failed to own up to.
But, have someone stuff a million spam emails through your relay
and get 10K angry emails back because your server admin contact
is in the expanded email headers and you'll realize it is your
problem too.
The good news is: FormMail is easy to fix.
Remove lines 74, 75 & 76
############
else {
$check_referer = 1;
}
###########
Those lines allow a submission with no referrer (Matt wasn't
thinking!) and allows a spammer to send
http://example.com/formmail.pl?message=GOTCHA&recipient=you
@your.com
from a location field (which does not produce a referrer).
That takes care of the lazy spammer. A professional spammer who
fakes the referrer with an LWP agent is a little harder. FormMail is
designed to be used by multiple domains sending emails to known
recipients. If you are letting visitors enter a recipient of their choice
you have a spam relay by design. But, if your recipient is in a
hidden field (as it should be) then the script needs to check the
submitted recipient against an array of approved recipients. To do
this you need to get a list of approved recipient emails from all of
the people authorized to have a form pointing to your FormMail
script. You then add them to an array on the line below $mailprog =
'/usr/lib/sendmail'; like so
@recipients = qw(me at my.com you at your.com);
(note the space between each email address)
Then on the line below &parse_form; place this line
unless("@recipients" =~
/$Config{'recipient'}/){&error('no_recipient')}
That will cause the script to exit reporting that no recipient was
submitted (technically not true). You can be nice to the bandit by
changing line 576 from "No Recipient was specified" to "An
Unauthorized Recipient was specified" but that's up to your sense
of 'fair play'.
Please, Heather, make the above changes. This is a hot topic on
many server mail lists. Subscribe to cobalt-users at list.cobalt.com
or cobalt-security at list.cobalt.com and bring up FormMail.pl and
watch the days of bitter ranting. BTW, the above fixes were tested
by numerous long-time subscribers to those 2 lists and passes the
minimum recommendations for hardening the script.
Feel free to contact me offlist if you have questions, need help or
want a fully hardened version of Matt's script.
Sincerly
keith
More information about the thelist
mailing list