Restraining PHP email scripts

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
Leao
Forum Commoner
Posts: 49
Joined: Mon Aug 21, 2006 8:57 pm
Location: London

Restraining PHP email scripts

Post by Leao »

Hi,

I'm using the attached PHP script to email variables sent via a Flash form onto my email account. The script works except I noticed that if I go to the PHP page containing the script directly and not via the form it automatically sends me a blank email. Presumably Internet robots that stumble across the page will also inadvertently send me loads of blank emails? What is the best way of avoiding this? I tried adding the following code to check if the $yourname variable is blank:

Code: Select all

if($yourname == "") 
{exit;}
However when I tried the same trick with some of the other variables the form stopped sending me emails altogether even when the variables weren't empty.

Your help is very much appreciated,

Thanks,

Leao

Code: Select all

<?php
$yourname = $_POST['yourname'];
$youremail = $_POST['youremail'];
$yourmessage = $_POST['yourmessage'];

$message = nl2br($yourmessage);

$to = 'mail@mydomain.com';

$subject = 'You have received a message';

$body = "<i>You have received a message via your website:</i><br><br><b>Name:</b><br>$yourname<br><br><b>Email:</b><br>$youremail<br><br><b>Message:</b><br>$message";

$body = wordwrap($body, 70);

$headers  = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n"; 
$headers .= "From: mail@mydomain.com\r\n";
$headers .= "Return-Path:mail@mydomain.com\r\n";
$headers .= "Reply-To: $youremail\r\n";
$headers .= 'X-Mailer: PHP/' . phpversion()."\r\n";

mail($to, $subject, $body, $headers, "-fmail@mydomain.com");
?>
Last edited by Leao on Wed Oct 11, 2006 3:10 pm, edited 1 time in total.
User avatar
andym01480
Forum Contributor
Posts: 390
Joined: Wed Apr 19, 2006 5:01 pm

Post by andym01480 »

1) Alter the robots.txt file in the document root to stop bots seeing the php script.

Code: Select all

User-agent: *
Disallow: /filename.php
Disallow: /directoryname/
Not sure if naughty bots just ignore that - I bet they do, so....

2) Check the form variables are set and not empty

Code: Select all

if (empty($_POST['email')) exit("You didn't enter an email address");
3) Check the email address is a valid one or those bots will use it to send spam by "injecting" (adding) naughty headers and content. Google for a email validating function or try http://www.ilovejackdaniels.com/php/ema ... alidation/
Leao
Forum Commoner
Posts: 49
Joined: Mon Aug 21, 2006 8:57 pm
Location: London

Post by Leao »

Thanks Andy, I tried your code for checking if the form variables are set and not empty:

Code: Select all

if (empty($_POST['youremail']) exit("You didn't enter an email address");
but it stopped emails being sent via the form altogether as well for some reason.

Do you have any idea why the above code doesn't work?

I'm not sure if a email validating function is necessary for my script as the form is within a Flash SWF that would be hard for a robot to get to.

Thanks again,

Leao
User avatar
RobertGonzalez
Site Administrator
Posts: 14293
Joined: Tue Sep 09, 2003 6:04 pm
Location: Fremont, CA, USA

Post by RobertGonzalez »

Check if the form was sent:

Code: Select all

<?php
if (isset($_POST['somefieldinyourform']))
{
    //process the emailing
}
else
{
    // redirect to form page
}
?>
User avatar
andym01480
Forum Contributor
Posts: 390
Joined: Wed Apr 19, 2006 5:01 pm

Post by andym01480 »

The if statement doesn't replace the need for

Code: Select all

$youremail = $_POST['youremail'];


Comment out the mail function with // at the start of the line for now and add an

Code: Select all

echo $body;
to check you are receiving the variables from your flash script.

You would definietely need to validate the email address! Your worry was that a bot or person would find your script. If they do they can create their own form to send their values to your email script or send them in the headers (don't know how). Sounds time consuming on their part - but they do do it! To send millions of <span style='color:red;text-decoration:blink' title='Alert a moderator!'>grilled spam</span> ads out from your server! Then your domain may get blacklisted by the anti-Spam programs or ISPs that haven't cottoned to this very old Spam technique.

The mantra on this site is never trust what is entered in a form!
User avatar
andym01480
Forum Contributor
Posts: 390
Joined: Wed Apr 19, 2006 5:01 pm

Post by andym01480 »

Site mods you are amazing. I put the name of a well known drug in my last post and it was replaced by <span style='color:red;text-decoration:blink' title='Alert a moderator!'>grilled spam</span>. How cool is that!!!!!
User avatar
RobertGonzalez
Site Administrator
Posts: 14293
Joined: Tue Sep 09, 2003 6:04 pm
Location: Fremont, CA, USA

Re: Restraining PHP email scripts

Post by RobertGonzalez »

Leao wrote:I'm using the attached PHP script to email variables sent via a Flash form onto my email account. The script works except I noticed that if I go to the PHP page containing the script directly and not via the form it automatically sends me a blank email.
This is happening because all of your code in that page assumes the page was called from the form. You have no checks in place to see if the form was posted, just an assumption that it was.

My suggestion was to check to see if there was a posted form field set, and if so, continue your processing of the email. If not, then your script knows that the form did not call the page and you can then have the processing of the email skipped and have the user taken to another page.
User avatar
RobertGonzalez
Site Administrator
Posts: 14293
Joined: Tue Sep 09, 2003 6:04 pm
Location: Fremont, CA, USA

Post by RobertGonzalez »

andym01480 wrote:Site mods you are amazing. I put the name of a well known drug in my last post and it was replaced by <span style='color:red;text-decoration:blink' title='Alert a moderator!'>grilled spam</span>. How cool is that!!!!!
You also double-posted, and we took care of that too. But thank feyd for the grilled spam. That is his baby.
Leao
Forum Commoner
Posts: 49
Joined: Mon Aug 21, 2006 8:57 pm
Location: London

Post by Leao »

It all works now! (See attached).

Thank you all very much,

leao

Code: Select all

<?php
if (isset($_POST['youremail']))
{

$yourname = $_POST['yourname'];
$youremail = $_POST['youremail'];
$yourmessage = $_POST['yourmessage'];

function check_email_address($youremail) {
  // First, we check that there's one @ symbol, and that the lengths are right
  if (!ereg("^[^@]{1,64}@[^@]{1,255}$", $youremail)) {
    // Email invalid because wrong number of characters in one section, or wrong number of @ symbols.
    return false;
  }
  // Split it into sections to make life easier
  $youremail_array = explode("@", $youremail);
  $local_array = explode(".", $youremail_array[0]);
  for ($i = 0; $i < sizeof($local_array); $i++) {
     if (!ereg("^(([A-Za-z0-9!#$%&'*+/=?^_`{|}~-][A-Za-z0-9!#$%&'*+/=?^_`{|}~\.-]{0,63})|(\"[^(\\|\")]{0,62}\"))$", $local_array[$i])) {
      return false;
    }
  }  
  if (!ereg("^\[?[0-9\.]+\]?$", $youremail_array[1])) { // Check if domain is IP. If not, it should be valid domain name
    $domain_array = explode(".", $youremail_array[1]);
    if (sizeof($domain_array) < 2) {
        return false; // Not enough parts to domain
    }
    for ($i = 0; $i < sizeof($domain_array); $i++) {
      if (!ereg("^(([A-Za-z0-9][A-Za-z0-9-]{0,61}[A-Za-z0-9])|([A-Za-z0-9]+))$", $domain_array[$i])) {
        return false;
      }
    }
  }
  return true;
}


if (check_email_address($youremail)) {


$message = nl2br($yourmessage);

$to = 'mail@mydomain.com';

$subject = 'A message has arrived via your website';

$body = "<i>You have received a message via your website:</i><br><br><b>Name:</b><br>$yourname<br><br><b>Email:</b><br>$youremail<br><br><b>Message:</b><br>$message";

$body = wordwrap($body, 70);

$headers  = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n"; 
$headers .= "From: mail@mydomain.com\r\n";
$headers .= "Return-Path:mail@mydomain.com\r\n";
$headers .= "Reply-To: $youremail\r\n";
$headers .= 'X-Mailer: PHP/' . phpversion()."\r\n";

mail($to, $subject, $body, $headers, "-fmail@mydomain.com");}


}

else
{echo "ERROR!";}

?>
User avatar
RobertGonzalez
Site Administrator
Posts: 14293
Joined: Tue Sep 09, 2003 6:04 pm
Location: Fremont, CA, USA

Post by RobertGonzalez »

You're welcome.
Leao
Forum Commoner
Posts: 49
Joined: Mon Aug 21, 2006 8:57 pm
Location: London

Post by Leao »

Just a thought with regards to the need for an email validating function - isn't it unnecessary in my script as I've forced the from: address in my $headers and mail function?

Thanks again,

Leao
User avatar
andym01480
Forum Contributor
Posts: 390
Joined: Wed Apr 19, 2006 5:01 pm

Post by andym01480 »

Good point! I think you are safe from header injection.

The bots and crackers will try to inject anyway and the email checker would reject spam attempts saving you getting lots of daft emails full of code instead of an email address

Could they try to use your form fields to put some naughty javascript into the message body as your email header is html????

Found another interesting site on the issue with an interesting looking function...http://www.tonyspencer.com/mt/archives/ ... ection.htm
Post Reply