Help optimising and updating enquiry form script

Discussion in 'PHP' started by Bally12345, Mar 7, 2009.

  1. #1
    am currently using a old mail form script I got a few years back and ideally I would like to optimise it as much as possible and even update so I dont get random emails submit via the form by bots.

    Currently my form script looks like this:
    <form name="form1" method="post" onSubmit="return checkform(this);" action="mailform.php">
    <input name="action" type="hidden" value="send">
    
    <table width="261" border="0" cellspacing="0" cellpadding="2" align="center">
      <tr>
        <td width="257" ><font face="Verdana" size="1" colour="#444444">Your Name*<input name="fname" type="text" size="40"></font></td>
          </tr>
      <tr>
        <td width="257" ><font face="Verdana" size="1" colour="#444444">Your E-mail Address*<input name="femail" type="text" size="40"></font></td>
      </tr>
      <tr>
        <td width="257" ><font face="Verdana" size="1" colour="#444444">Address Line 1<input name="fadd1" type="text" size="40"></font></td>
      </tr>
      <tr>
        <td width="257" ><font face="Verdana" size="1" colour="#444444">Address Line 2<input name="fadd2" type="text" size="40"></font></td>
      </tr>
      <tr>
        <td width="257" ><font face="Verdana" size="1" colour="#444444">City<input name="fcity" type="text" size="40"></font></td>
      </tr>
      <tr>
        <td width="257" ><font face="Verdana" size="1" colour="#444444">Postal Code<br><input name="fpost" type="text" size="8" maxlength="8"> e.g. AB1C 2DE</font></td>
      </tr>
      <tr>
        <td width="257" ><font face="Verdana" size="1" colour="#444444">Contact number<br><input name="fnumber" type="text" size="15" maxlength="15"> e.g. 0000 123 1234</font></td>
      </tr>
      <tr>
        <td width="257" ><font face="Verdana" size="1" colour="#444444">Subject*<input name="subject" type="text" size="40"></font></td>
      </tr>
      <tr>
        <td width="257" ><font face="Verdana" size"1" colour="#444444">Message*<br>
        <textarea name="fmess" cols="35" style="height: 66px"></textarea></font></td>
      </tr>
         <td width="257">
    	 <font face="Verdana" size="1" colour="#444444">
    	 <input name="cmdSend" type="submit" value="Send">&nbsp;
    	 <input name="cmdReset" type="reset" value="Reset"> </font>
    	</td>
      </tr>
    </form>
    Code (markup):
    and the actual mailform script looks like this:
    <?php 
    
    if(!isset($action)){ 
    
    ?> 
    
    <?php 
    }else{ 
    function validEmail($femail) { 
    if (eregi("^[a-z0-9]+([-_\.]?[a-z0-9])+@[a-z0-9]+([-_\.]?[a-z0-9])+\.[a-z]{2,4}", $femail)) { 
       return TRUE; 
    } else { 
           return FALSE; 
      } 
    } 
    if (validEmail($femail)) { 
    
    $message = "$fname has made an enquiry about $subject 
    
    $fmess 
    
    Their contact details are: 
    $fname 
    $fadd1 
    $fadd2 
    $fcity 
    $fpost 
    
    $fnumber 
    $femail"; 
    
    $toemail = "info@domain.com"; 
     $from = $fname . "<$femail>"; 
     $headers = "From: $from \r\n"; 
     if($rdType == 1){ 
       $headers .= "MIME-Version: 1.0\n" . "Content-type: text/html; charset=iso-8859-1"; 
       $message = stripslashes($message); 
     }else{ 
       $headers .= "MIME-Version: 1.0\n" . "Content-type: text/plain; charset=iso-8859-1"; 
     } 
    
    
     $ok = @mail($toemail, $subject, $message, $headers); 
    
      if ($ok) { 
       echo "<meta HTTP-EQUIV=refresh content=4;url=index.html><body bgcolor=#FFFFFF> 
    <center><font face='Verdana' size='2' colour='#444444' class='general'>Your enquiry has been sent successfully 
    <br>Please allow upto 48 hours for a reply.  
    <br>If you cannot wait for a reply please feel free to call person directly. 
    <br><br>Thank you</font></center>"; 
      } else { 
       echo "<meta HTTP-EQUIV=refresh content=4;url=enquiry.html><body bgcolor=#FFFFFF> 
    <center><font face='Verdana' size='2' colour='#444444' class='general'>Your email could not be sent. Please go back and check all details are filled in correctly</font></center>"; 
      } 
     } else { 
     echo "<meta HTTP-EQUIV=refresh content=6;url=enquiry.html><body bgcolor=#FFFFFF> 
    <center><font face='Verdana' size='2' colour='#444444' class='general'>You have not entered a valid email address please go back and enter a valid email address as this will be used to reply to your enquiry</font></center>"; 
     } 
    
     } 
    
    ?> 
    PHP:
    Can anyone see any errors also how can I add some sort of spam protection so I dont get emails about miracle pills etc. One of the main problems is email injection.

    TIA
     
    Bally12345, Mar 7, 2009 IP
  2. DGK

    DGK Peon

    Messages:
    73
    Likes Received:
    1
    Best Answers:
    0
    Trophy Points:
    0
    #2
    Get some free captcha :)
     
    DGK, Mar 7, 2009 IP
  3. exodus

    exodus Well-Known Member

    Messages:
    1,900
    Likes Received:
    35
    Best Answers:
    0
    Trophy Points:
    165
    #3
    I think you should change up the html to be external css file and then do something like recaptcha.com to not allow webmail spam to be sent using that web form.
     
    exodus, Mar 8, 2009 IP
  4. Bally12345

    Bally12345 Peon

    Messages:
    30
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #4
    Is there anyway I can improve the php mailform before I had captcha?
     
    Bally12345, Mar 8, 2009 IP
  5. SmallPotatoes

    SmallPotatoes Peon

    Messages:
    1,321
    Likes Received:
    41
    Best Answers:
    0
    Trophy Points:
    0
    #5
    1. It looks like your server has register_globals on and magic_quotes on, which is a miserable way to try to get anything done with PHP, not to mention a security nightmare. Is there actually any shared host that still does this? Shame on them.

    2. You do have an email injection problem, assuming that $fname comes straight from the user's form posting. Imagine that I submit a form to you where the "Your name" field is set to:

    Bob Smith <bob@spamco.com>
    Cc: victim1@yahoo.com, victim2@gmail.com, victim3@msn.com, (1000 more victims)
    
    Buy our viagra now! Special discount available on pills to make your 
    schlong stay stronger for longer!
    Code (markup):
    Yes, as your script is currently written, it is easy to send that value for $fname.

    All the victims on their fake Cc: line will receive the viagra spam, sent from your server.

    ANYTHING that goes into the 4th argument of mail() MUST be sanitized character-by-character, or your script will be found by bots and used to blast out spam. You may never find out until you lose your hosting account. Use a preg filter that only allows through characters that are clearly legitimate in the context.
     
    SmallPotatoes, Mar 8, 2009 IP
  6. Bally12345

    Bally12345 Peon

    Messages:
    30
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #6
    Thank you for your reply I kinda redone the script but getting the following error:
    Parse error: syntax error, unexpected '}' in /mnt/w0108/d10/s10/b028bc78/www/domain.com/test.php on line 98

    <?php  
    function validEmail($femail) 
    { 
       $isValid = true; 
       $atIndex = strrpos($femail, "@"); 
       if (is_bool($atIndex) && !$atIndex) 
       { 
          $isValid = false; 
       } 
       else 
       { 
          $domain = substr($femail, $atIndex+1); 
          $local = substr($femail, 0, $atIndex); 
          $localLen = strlen($local); 
          $domainLen = strlen($domain); 
          if ($localLen < 1 || $localLen > 64) 
          { 
             // local part length exceeded 
             $isValid = false; 
          } 
          else if ($domainLen < 1 || $domainLen > 255) 
          { 
             // domain part length exceeded 
             $isValid = false; 
          } 
          else if ($local[0] == '.' || $local[$localLen-1] == '.') 
          { 
             // local part starts or ends with '.' 
             $isValid = false; 
          } 
          else if (preg_match('/\\.\\./', $local)) 
          { 
             // local part has two consecutive dots 
             $isValid = false; 
          } 
          else if (!preg_match('/^[A-Za-z0-9\\-\\.]+$/', $domain)) 
          { 
             // character not valid in domain part 
             $isValid = false; 
          } 
          else if (preg_match('/\\.\\./', $domain)) 
          { 
             // domain part has two consecutive dots 
             $isValid = false; 
          } 
          else if 
    (!preg_match('/^(\\\\.|[A-Za-z0-9!#%&`_=\\/$\'*+?^{}|~.-])+$/', 
                     str_replace("\\\\","",$local))) 
          { 
             // character not valid in local part unless  
             // local part is quoted 
             if (!preg_match('/^"(\\\\"|[^"])+"$/', 
                 str_replace("\\\\","",$local))) 
             { 
                $isValid = false; 
             } 
          } 
       } 
       return $isValid; 
    } 
    
    $message = "$fname has made an enquiry about $subject  
    
    $fmess  
    
    Their contact details are:  
    $fname  
    $fadd1  
    $fadd2  
    $fcity  
    $fpost  
    
    $fnumber  
    $femail";  
    
    $toemail = "info@domain.com";  
     $from = $fname . "<$femail>";  
     $headers = "From: $from \r\n";  
     if($rdType == 1){  
       $headers .= "MIME-Version: 1.0\n" . "Content-type: text/html; charset=iso-8859-1";  
       $message = stripslashes($message);  
     }else{  
       $headers .= "MIME-Version: 1.0\n" . "Content-type: text/plain; charset=iso-8859-1";  
     }  
    
     $ok = @mail($toemail, $subject, $message, $headers);  
    
      if ($ok) {  
       echo "<meta HTTP-EQUIV=refresh content=4;url=index.html><body bgcolor=#FFFFFF>  
    <center><font face='Verdana' size='2' colour='#444444' class='general'>Your enquiry has been sent successfully  
    <br>Please allow upto 48 hours for a reply.   
    <br>If you cannot wait for a reply please feel free to call name removed directly.  
    <br><br>Thank you</font></center>";  
      } else {  
       echo "<meta HTTP-EQUIV=refresh content=4;url=enquiry.html><body bgcolor=#FFFFFF>  
    <center><font face='Verdana' size='2' colour='#444444' class='general'>Your email could not be sent. Please go back and check all details are filled in correctly</font></center>";  
      }  
     } else {  
     echo "<body bgcolor=#FFFFFF>
    <center><font face='Verdana' size='2' colour='#444444' class='general'>You have not entered a valid email address please <a href='javascript:history.go(-1)'>go back</a> and enter a valid email address as this will be used to reply to your enquiry</font></center>";
     }
    
     }  
    
    ?> 
    PHP:
    Any suggestions? The problem seems to be with
     } else { 
    PHP:
     
    Bally12345, Mar 8, 2009 IP
  7. SmallPotatoes

    SmallPotatoes Peon

    Messages:
    1,321
    Likes Received:
    41
    Best Answers:
    0
    Trophy Points:
    0
    #7
    else if (preg_match('/\\.\\./', $local))
    (!preg_match('/^(\\\\.|[A-Za-z0-9!#%&`_=\\/$\'*+?^{}|~.-])+$/', 
                     str_replace("\\\\","",$local))) 
    if (!preg_match('/^"(\\\\"|[^"])+"$/', 
                 str_replace("\\\\","",$local)))
    Code (markup):
    I can't even begin to imagine what's going on with all those backslashes. They're escaping a quote which is leaving a string open which is why you're getting an error message somewhat removed from the location of the actual problem.

    I suggest reading the manual pages and examples and writing your own code; copying and pasting random bits from random places is a painful way to learn anything!
     
    SmallPotatoes, Mar 8, 2009 IP
  8. exodus

    exodus Well-Known Member

    Messages:
    1,900
    Likes Received:
    35
    Best Answers:
    0
    Trophy Points:
    165
    #8
    Using a php Formater I found that some of your if else statements are not present. See the bottom portion of this. Looks like you were going to add a validEmail check, but only half way added the checking statement or placed it out of place.


    <?php
      if (!isset($action))
      {
          echo '<form name="form1" method="post" onSubmit="return checkform(this);" action="mailform.php">
    <input name="action" type="hidden" value="send">
    
    <table width="261" border="0" cellspacing="0" cellpadding="2" align="center">
      <tr>
        <td width="257" ><font face="Verdana" size="1" colour="#444444">Your Name*<input name="fname" type="text" size="40"></font></td>
          </tr>
      <tr>
        <td width="257" ><font face="Verdana" size="1" colour="#444444">Your E-mail Address*<input name="femail" type="text" size="40"></font></td>
      </tr>
      <tr>
        <td width="257" ><font face="Verdana" size="1" colour="#444444">Address Line 1<input name="fadd1" type="text" size="40"></font></td>
      </tr>
      <tr>
        <td width="257" ><font face="Verdana" size="1" colour="#444444">Address Line 2<input name="fadd2" type="text" size="40"></font></td>
      </tr>
      <tr>
        <td width="257" ><font face="Verdana" size="1" colour="#444444">City<input name="fcity" type="text" size="40"></font></td>
      </tr>
      <tr>
        <td width="257" ><font face="Verdana" size="1" colour="#444444">Postal Code<br><input name="fpost" type="text" size="8" maxlength="8"> e.g. AB1C 2DE</font></td>
      </tr>
      <tr>
        <td width="257" ><font face="Verdana" size="1" colour="#444444">Contact number<br><input name="fnumber" type="text" size="15" maxlength="15"> e.g. 0000 123 1234</font></td>
      </tr>
      <tr>
        <td width="257" ><font face="Verdana" size="1" colour="#444444">Subject*<input name="subject" type="text" size="40"></font></td>
      </tr>
      <tr>
        <td width="257" ><font face="Verdana" size"1" colour="#444444">Message*<br>
        <textarea name="fmess" cols="35" style="height: 66px"></textarea></font></td>
      </tr>
         <td width="257">
       <font face="Verdana" size="1" colour="#444444">
       <input name="cmdSend" type="submit" value="Send">&nbsp;
       <input name="cmdReset" type="reset" value="Reset"> </font>
      </td>
      </tr>
    </form>';
      }
      else
      {
          
          
          function validEmail($femail)
          {
              $isValid = true;
              $atIndex = strrpos($femail, "@");
              if (is_bool($atIndex) && !$atIndex)
              {
                  $isValid = false;
              }
              else
              {
                  $domain = substr($femail, $atIndex + 1);
                  $local = substr($femail, 0, $atIndex);
                  $localLen = strlen($local);
                  $domainLen = strlen($domain);
                  if ($localLen < 1 || $localLen > 64)
                  {
                      // local part length exceeded
                      $isValid = false;
                  }
                  elseif ($domainLen < 1 || $domainLen > 255)
                  {
                      // domain part length exceeded
                      $isValid = false;
                  }
                  elseif ($local[0] == '.' || $local[$localLen - 1] == '.')
                  {
                      // local part starts or ends with '.'
                      $isValid = false;
                  }
                  elseif (preg_match('/\\.\\./', $local))
                  {
                      // local part has two consecutive dots
                      $isValid = false;
                  }
                  elseif (!preg_match('/^[A-Za-z0-9\\-\\.]+$/', $domain))
                  {
                      // character not valid in domain part
                      $isValid = false;
                  }
                  elseif (preg_match('/\\.\\./', $domain))
                  {
                      // domain part has two consecutive dots
                      $isValid = false;
                  }
                  elseif (!preg_match('/^(\\\\.|[A-Za-z0-9!#%&`_=\\/$\'*+?^{}|~.-])+$/', str_replace("\\\\", "", $local)))
                  {
                      // character not valid in local part unless 
                      // local part is quoted
                      if (!preg_match('/^"(\\\\"|[^"])+"$/', str_replace("\\\\", "", $local)))
                      {
                          $isValid = false;
                      }
                  }
              }
              return $isValid;
          }
          
          $message = "$fname has made an enquiry about $subject 
    
    $fmess 
    
    Their contact details are: 
    $fname 
    $fadd1 
    $fadd2 
    $fcity 
    $fpost 
    
    $fnumber 
    $femail";
          
          $toemail = "info@domain.com";
          $from = $fname . "<$femail>";
          $headers = "From: $from \r\n";
          if ($rdType == 1)
          {
              $headers .= "MIME-Version: 1.0\n" . "Content-type: text/html; charset=iso-8859-1";
              $message = stripslashes($message);
          }
          else
          {
              $headers .= "MIME-Version: 1.0\n" . "Content-type: text/plain; charset=iso-8859-1";
          }
          
          $ok = @mail($toemail, $subject, $message, $headers);
          
          if ($ok)
          {
              echo "<meta HTTP-EQUIV=refresh content=4;url=index.html><body bgcolor=#FFFFFF><center><font face='Verdana' size='2' colour='#444444' class='general'>Your enquiry has been sent successfully <br>Please allow upto 48 hours for a reply.   <br>If you cannot wait for a reply please feel free to call name removed directly. <br><br>Thank you</font></center>";
          }
          else
          {
              echo "<meta HTTP-EQUIV=refresh content=4;url=enquiry.html><body bgcolor=#FFFFFF><center><font face='Verdana' size='2' colour='#444444' class='general'>Your email could not be sent. Please go back and check all details are filled in correctly</font></center>";
          }
      /**  WHAT ARE YOU DOING HERE?
      }
      else
      {
          echo "<body bgcolor=#FFFFFF><center><font face='Verdana' size='2' colour='#444444' class='general'>You have not entered a invalid email address please <a href='javascript:history.go(-1)'>go back</a> and enter a valid email address as this will be used to reply to your enquiry</font></center>";
      }
      **/
    }
    ?>
    PHP:
     
    exodus, Mar 8, 2009 IP
  9. Bally12345

    Bally12345 Peon

    Messages:
    30
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #9
    If im honest I havent a clue that was already there in the original script which a friend coded for me a long time ago. Really I dont think that needs to be there or it could actually replace the bit above... Could really do with starting the form from scratch....
     
    Bally12345, Mar 9, 2009 IP
  10. Bally12345

    Bally12345 Peon

    Messages:
    30
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #10
    Right I can get this mailform to send mail submitted from my html form but it does check any email validation

    <?php
      function validEmail($email) {
          $isValid = true;
          $atIndex = strrpos($email, "@");
          if (is_bool($atIndex) && !$atIndex) {
              $isValid = false;
          } else {
              $domain = substr($email, $atIndex + 1);
              $local = substr($email, 0, $atIndex);
              $localLen = strlen($local);
              $domainLen = strlen($domain);
              if ($localLen < 1 || $localLen > 64) {
                  // local part length exceeded
                  $isValid = false;
              } elseif ($domainLen < 1 || $domainLen > 255) {
                  // domain part length exceeded
                  $isValid = false;
              } elseif ($local[0] == '.' || $local[$localLen - 1] == '.') {
                  // local part starts or ends with '.'
                  $isValid = false;
              } elseif (preg_match('/\\.\\./', $local)) {
                  // local part has two consecutive dots
                  $isValid = false;
              } elseif (!preg_match('/^[A-Za-z0-9\\-\\.]+$/', $domain)) {
                  // character not valid in domain part
                  $isValid = false;
              } elseif (preg_match('/\\.\\./', $domain)) {
                  // domain part has two consecutive dots
                  $isValid = false;
              } elseif (!preg_match('/^(\\\\.|[A-Za-z0-9!#%&`_=\\/$\'*+?^{}|~.-])+$/', str_replace("\\\\", "", $local))) {
                  // character not valid in local part unless 
                  // local part is quoted
                  if (!preg_match('/^"(\\\\"|[^"])+"$/', str_replace("\\\\", "", $local))) {
                      $isValid = false;
                  }
              }
              if ($isValid && !(checkdnsrr($domain, "MX") || checkdnsrr($domain, "A"))) {
                  // domain not found in DNS
                  $isValid = false;
              }
          }
          return $isValid;
      }
      
      $message = "$fname has made an enquiry about $subject 
    
    $fmess 
    
    Their contact details are: 
    $fname 
    $fadd1 
    $fadd2 
    $fcity 
    $fpost 
    
    $fnumber 
    $femail";
      
      $toemail = "info@domain.co.uk";
      $from = $fname . "<$femail>";
      $headers = "From: $from \r\n";
      if ($rdType == 1) {
          $headers .= "MIME-Version: 1.0\n" . "Content-type: text/html; charset=iso-8859-1";
          $message = stripslashes($message);
      } else {
          $headers .= "MIME-Version: 1.0\n" . "Content-type: text/plain; charset=iso-8859-1";
      }
      
      $ok = @mail($toemail, $subject, $message, $headers);
      
      if ($ok) {
          echo "<meta HTTP-EQUIV=refresh content=4;url=index.html><body bgcolor=#FFFFFF><center><font face='Verdana' size='2' colour='#444444' class='general'>Your enquiry has been sent successfully <br>Please allow upto 48 hours for a reply.   <br>If you cannot wait for a reply please feel free to call name removed directly. <br><br>Thank you</font></center>";
      } else {
          echo "<body bgcolor=#FFFFFF><center><font face='Verdana' size='2' colour='#444444' class='general'>You have entered a invalid email address please <a href='javascript:history.go(-1)'>go back</a> and enter a valid email address as this will be used to reply to your enquiry</font></center>";
      }
    ?>
    PHP:
    It just submits what ever is entered. So for example for email field someone could just enter vi**a and it will give them thank you message.
     
    Bally12345, Mar 9, 2009 IP
  11. SmallPotatoes

    SmallPotatoes Peon

    Messages:
    1,321
    Likes Received:
    41
    Best Answers:
    0
    Trophy Points:
    0
    #11
    You have inserted someone's "validEmail()" function (and a lot of spare backslashes) but you are never calling it.

    Before actually going ahead with mail(), you need to pass the email addresses you want to check to validEmail(), and if the result is false, then don't send the message.

    Instead, you are checking the result of mail(), which won't tell you whether the email address was invalid.
     
    SmallPotatoes, Mar 9, 2009 IP
  12. Bally12345

    Bally12345 Peon

    Messages:
    30
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #12
    So whats the solution?
     
    Bally12345, Mar 9, 2009 IP
  13. SmallPotatoes

    SmallPotatoes Peon

    Messages:
    1,321
    Likes Received:
    41
    Best Answers:
    0
    Trophy Points:
    0
    #13
    Before actually going ahead with mail(), you need to pass the email addresses you want to check to validEmail(), and if the result is false, then don't send the message.
     
    SmallPotatoes, Mar 9, 2009 IP