Welcome to the Geeks & God Static Archive. Read more »

Tell a friend pages

Joined: 11/28/2008

Hi

Just wondering - is a 'tell a friend' page, where the user enters a friend's address, inherently able to be spammed?

Is there any way round this, short of a CAPTCHA image confirmation?

Or how about splitting the email field in two, so the user enters each part of the address separately, and the script adds the @ in later/

blessings and thanks

Tony

Online outreach:
Internet Evangelism Day
Helping church websites:
Church Websites

Joined: 11/28/2008
Shouldn't be. I mean you are

Shouldn't be. I mean you are allowing anyone to send an email to anyone, but you should limit how many recipients there are, filter all input for spam-type data (Content-type headers etc), restrict the length of the user-submitted message, and you could even IP-restrict the use of the form so one IP address can only send out say 2 or three per hour.

Paul Davey
Whitford Church
"Everyone who calls on the name of the Lord will be saved." Romans 10:13
"For all have sinned and fall short of the glory of God, and are justified

Joined: 11/28/2008
Thanks Paul.Now, even if I do

Thanks Paul.

Now, even if I do that, I take there is nothing to stop a spam bot submitting individual single spam messages to unwitting third parties using a tellafriend form.

I have heard of clever tricks to hid extra form fields to confuse bots.

But I still wonder if splitting the friend's email form into two parts - before and after the @ sign, and then also excluding any added @ sign from either field, would more or less make it impossible to spam?

Coupled with other stuff to stop anything being hidden in the message area.

Blessings

Tony

Online outreach:
Internet Evangelism Day
Helping church websites:
Church Websites

Joined: 11/28/2008
You can also look for

You can also look for keywords: Viagra, oxycodine, etc

TJ SINGLETON

Joined: 11/28/2008
soon @ Nov 9 2006,
QUOTE(soon @ Nov 9 2006, 06:17 PM)
But I still wonder if splitting the friend's email form into two parts - before and after the @ sign, and then also excluding any added @ sign from either field, would more or less make it impossible to spam?

Impossible? No. Perhaps slightly trickier, but remember you can easily make your form non-standard so any spam will have to be done manually. Regularly changing hidden inputs (that are checked server-side) are good - it forces people to only submit the form from your web site only. I have heard it suggested there are spammers who employ the services of people to fill out captcha forms (i.e. one at a time manual forms) to do a range of things like sign up to forums. Perhaps someone is paid a few $ an hour to fill out as many as they can, I imagine they could do quite a few in an hour. That's a real person filling it out. If you stop your form being used to mass-mail, it will be less useful than other people's forms (the old "make your car harder to steal than your neighbour's" trick).

Paul Davey
Whitford Church
"Everyone who calls on the name of the Lord will be saved." Romans 10:13
"For all have sinned and fall short of the glory of God, and are justified

Joined: 11/28/2008
I wish I had some spam bots

I wish I had some spam bots to dicect it'd be a nice to see what they look for, and how you could cloak for them.

TJ SINGLETON

Joined: 11/28/2008
Hello Tony.I pray you are

Hello Tony.

I pray you are well.

I have been looking at the issue of PHP mail forms and security as well.

Here are some of the things I have observed.

Spammers exploit mail forms with bots (all automatic), a combo of human interaction and bots (semi-automatic) , and by total human interaction (manual).

Spammers can use a web-based form to spam on a mass bases or in small/one by one email batches.

We fight spammers in similar ways with:

1. Validation scripts (automatic)
-- checking for a correctly formed send email address
-- checking for a valid mx record of the sender's address
-- logging and flood control against an IP addresses sending too many emails at once
-- checking email subject and body for spam words

2. Securing our mail servers against being an open relay or sending a number past a set threshold (automatic)

3. Banning ranges of user ip addresses and banning against ip addresses which show senders to be in a suspicious geography (automatic)

4. Server-side script stuff like changing up and checking hidden variables and breaking steps up in different ways to throw off bots

5. CAPTCHA with image or math question validation - sometimes hurting our site's accessibility (automatic)

The first 4 help primarily with mass spammers. They help, but they can all be overcome by spammers with spoofing. CAPTCHA can also help, but may limit accessibility or even just inclination to send.

The above only help somewhat with fighting mass spam, and still cannot prevent the determined spammer from using your form from time to time to send a single or small amount of spam.

If you combine the above ( or some of the above) you would have the semi-automatic approach, using the below only when when emails get past the above checks.

5. Queuing all tell-a-friend emails until they are manually verified by the webmaster as valid and then set to allow to send.

Hope this helps.

In Christ,
Sean

Joined: 11/28/2008
Thanks folksWell, I switched

Thanks folks

Well, I switched my email contact form to the following script:
http://www.safalra.com/programming/php/con...-feedback-form/

and found it killed most spam from the form. I was therefore thinking of modifying it to improve my tell a friend form too.

The only spam getting through now (so far) is a single percent character in the body of the email.

So I'd like to do the following things, if you think these would help:

1) validate the sender's email address by domain. I used to do this in my old script using

CODE
// check for valid domain name
$ok = TRUE;
$ok = eregi( "^[_.0-9a-z-]+@([0-9a-z][0-9a-z-]+.)+[a-z]{2,3}$", $email,
$check);
$ok = getmxrr(substr(strstr($check[0], '@'), 1), $dummy);
if($ok === false)
{
$host = substr($email, strpos($email, '@') + 1);
if(gethostbyname($host) != $host)
{
$ok = true;
}

but I don't know how to insert that into the new script

2) Add a maximum and minimum number of characters in the text area to be allowed. I used to have a checker for a maximum, thus

CODE
<?php $body_len = preg_match_all('/./', $str, $dummy); ?>

in the form and

CODE
$str = $text; $text_len = strlen($str);
if($text_len > 800) { $error .= "Sorry, you have used more than permitted 800 characters in your message. Total was $text_len - please shorten your message.<br>"; }

in the checking procedure. But I don't know how to put that into the new all-one-page script

3) Hidden form filed - and if a bot puts anything into them, the mail is cancelled.

I take it this would mean, in the above script, definining the presence of code in a hidden field as $crack

CODE
if ($_POST){
    $email=stripslashes($_POST['email']);
    $body=stripslashes($_POST['body']);
    // validate e-mail address
    $valid=eregi('^([0-9a-z]+[-._+&])*[0-9a-z]+@([-0-9a-z]+[.])+[a-z]{2,6}$',$email);
    $crack=eregi("(r|n)(to:|from:|cc:|(anti-spam-(anti-spam-(anti-spam-(anti-spam-bcc:)))))",$body);
    if ($email && $body && $valid && !$crack){
      if (mail($to,$messageSubject,$body,'From: '.$email."rn")
          && mail($email,$confirmationSubject,$confirmationBody.$body,'From: '.$to."rn")){
        $displayForm=false;

How would I insert a new line here to check that if field name 'whatever' had content, it would be treated as spam?

4)

QUOTE
Regularly changing hidden inputs (that are checked server-side) are good - it forces people to only submit the form from your web site only.

What, in practice, does this mean. Just make code changes to the form from time to time?

Also, I'm unsure how to add another field to the form - ie where in the processing code should I insert $anotherfield. I have tried, but it gives an error.

Blessings and thanks

Tony

Online outreach:
Internet Evangelism Day
Helping church websites:
Church Websites

Joined: 11/28/2008
I can answer 4 easily

I can answer 4) easily enough: In practice, you could either change it manually yourself in the script/form, just choosing some word or random string each month, for example. OR, You could create an algorithm that generated a string based on the date (month) and something else - perhaps hashing it. The only thing you need really is to be able to know, when the form is submitted, what the hidden field's value SHOULD be. Of course, just generating a random string would make this impossible, so something based on the month can be a good way to go. (There is the small, momentary risk at the change of the month).

The $crack line above is a bit meaningless - the $body variable is actually not going to pose any risk, and can legitimately contain new-line characters (I presume that is what the r|n is supposed to match, though they should have a \ before them). The things it should check for are Content-type etc.

You could check for minimum/maximum length in the script above - find this line (note: stripslashes should only be done when magic_quotes is on):

CODE
if ($email && $body && $valid && !$crack){

and put on the line after it:

CODE
if ((strlen($body) > 800) || (strlen($body) < 5)) {
?>
<p>
Sorry, you have used more than permitted 800 characters in your message. Total was <?php echo strlen($body); ?> - please shorten your message.</p>
<?php
}

And change the line:

CODE
      if (mail($to,$messageSubject,$body,'From: '.$email."\r\n")
          && mail($email,$confirmationSubject,$confirmationBody.$body,'From: '.$to."\r\n")){

to:

CODE
      elseif (mail($to,$messageSubject,$body,'From: '.$email."\r\n")
          && mail($email,$confirmationSubject,$confirmationBody.$body,'From: '.$to."\r\n")){

Paul Davey
Whitford Church
"Everyone who calls on the name of the Lord will be saved." Romans 10:13
"For all have sinned and fall short of the glory of God, and are justified

Joined: 11/28/2008
bobbymac @ Nov 11 2006,
QUOTE(bobbymac @ Nov 11 2006, 03:02 PM)
I can answer 4) easily enough: In practice, you could either change it manually yourself in the script/form,

Thanks Paul! Well, how's this - a hidden form field:

CODE
<tr><td>
<span style="color:white;font-size:1px;"><label for="name">Your name:</label></span>
</td>
<td>
<input title="Visually impaired users: do not enter anything on this line" class="text" type="text" name="name" id="name" value=<? print(date("M")); ?>" style="width:1px;height:1px;border:none;">
</td></tr>

But then I will need a line that says if $name is not equal to date("M", it iwll be $crack? Sorry, how do I write that, and where should it go?

QUOTE
just choosing some word or random string each month, for example.

OK with just the month name a I have done? Or some extra fixed stuff round it too, so a bot doesn't try to guess?

QUOTE
The $crack line above is a bit meaningless - the $body variable is actually not going to pose any risk, and can legitimately contain new-line characters (I presume that is what the r|n is supposed to match, though they should have a before them). The things it should check for are Content-type etc.

What do you recommend? I understood that bots would get dodgy stuff in the body to try and bcc an email?

Given that some of the spam I've been getting contains web addresses, I'd also like to have a line that banned html, presumably banning pointy brackets would be sufficient.

QUOTE
You could check for minimum/maximum length in the script above - find this line (note: stripslashes should only be done when magic_quotes is on):

How should magic quotes be put on?

QUOTE
Sorry, you have used more than permitted 800 characters in your message.

Great, that minimum and maximum length works fine! Bless you.

And one final query please :-)

My old form had the code which actually checked if the domain existed. Not just if it was a valid email construction. So if you put in a fictitious email address, it gave an error message.

This was the code it used:

CODE
// check for valid domain name
$ok = TRUE;
$ok = eregi( "^[_.0-9a-z-]+@([0-9a-z][0-9a-z-]+.)+[a-z]{2,3}$", $email,
$check);
$ok = getmxrr(substr(strstr($check[0], '@'), 1), $dummy);
if($ok === false)
{
$host = substr($email, strpos($email, '@') + 1);
if(gethostbyname($host) != $host)
{
$ok = true;

How can I add that to the new form?

Oh, and I am not quite sure how to add a geniune extra field $anotherfield to presumably this line:
if ($email && $body && $valid && !$crack){

I did try, but it gave an error.

Also, I am not sure that this line is working

CODE
    $crack=eregi("(r|n)(to:|from:|cc:|(anti-spam-bcc:))",$body);

I take that to mean that it would treat as an error from: cc: or (anti-spam-bcc:) in the body of the email. But they don't throw up any error.

Also, I did try

CODE
$crack=(eregi("(r|n)(to:|from:|cc:|(anti-spam-bcc:))",$body)) or (eregi("[<][>]",$body))

and that does not throw up any error if html brackets are put in the body.

Blessings and mega thanks

Tony

Online outreach:
Internet Evangelism Day
Helping church websites:
Church Websites

Joined: 11/28/2008
I managed to get this line to

I managed to get this line to work, and throw up an error for html or email header code in the body:

CODE
$crack=(eregi("(to:|from:|cc:|(anti-spam-(anti-spam-bcc:))|<|>)",$body)) or (strlen($_POST["name"]) > 0);

What I am stuck on is

1. How to add a new legitimate input area called, say, $information

2. How to add a hidden input area called, say, $name

My attempts to make the above line pick up on a hidden field called $name containing any characters are just not noticed and just go through normally without any error message.

And my attempt to add a new legitimate input area to the form and adding it to this line

CODE
elseif (mail($to,$messageSubject,$body,'From: '.$email."rn")

caiuse an error.

Thanks for any wisdom.

Blessings

Tony

Online outreach:
Internet Evangelism Day
Helping church websites:
Church Websites