Help with banning certain words on contact form?

Discussion in 'PHP' started by CanaryWoolf, Feb 15, 2006.

  1. #1
    Can anyone help? I'm getting fed up with the continous stream of spam coming through my contact form (generated by some automated bot) with link to viagra, doxycycline hyclate, sildenafil citrate and various other pills.


    Currently the form on each page of the website is simple:

    <form action="ok.php" method="POST">
    
        <strong>Your Name</strong><br />
         <input name="sender_name" size="18" type="text" /><br />
         <br />
         <strong>Your Company</strong><br />
         <input name="company" size="18" type="text" /><br />
         <br />
         <strong>Your E-Mail Address</strong><br />
         <input name="sender_email" size="18" type="text" /> <br />
         <br />
         <strong>Telephone</strong><br />
         <input name="telephone" size="18" type="text" /><br />
         <br />
         <strong>Enquiry</strong><br />
         <textarea name="message" rows="10" cols="14"></textarea>         <input name="page" type="hidden" value="links page">
    
         <div align="left">
         <br />
         <input type="submit" value="send" />
         <input type="reset" value="clear" />
         </div>         
        </form>
    Code (markup):
    The form is then posted to a confirmation page where the following script actions and sends the content:

    
    
    <?php
    $to = myemail@company.com; 
    //mail string
    $msg = "Enquiry from\t$_POST[page]\n";
    $msg .= "Name:\t$_POST[sender_name]\n";
    $msg .= "E-mail:\t$_POST[sender_email]\n";
    $msg .= "Telephone:\t$_POST[telephone]\n";
    $msg .= "Company:\t$_POST[company]\n";
    $msg .= "Message:\t$_POST[message]\n";
    //set up e-mail
    
    $subject = "Message from website\n";
    $mailheaders = "From:\t$_POST[sender_email]\n";
    $mailheaders .= "Reply to:\t$_POST[sender_email]";
    //send mail
    mail($to, $subject, $msg, $mailheaders);
    
    ?>
    Code (markup):
    Can anyone suggest any script which I can add to ban certain words?
    The bot correctly fills out all of the fields so no normal validation would work
     
    CanaryWoolf, Feb 15, 2006 IP
  2. mad4

    mad4 Peon

    Messages:
    6,986
    Likes Received:
    493
    Best Answers:
    0
    Trophy Points:
    0
    #2
    try this:
    
    $filestring="$_POST[sender_name] $_POST[message]";//add all your fields to this line
    $findme  = 'viagra';
    $pos = strpos($filestring, $findme);
    
    // Note the use of ===.  Simply == would not work as expected
    if ($pos === false) {
       echo "OK";
    } else {
       echo "The string '$findme' was found - error";
       }
    
    PHP:
     
    mad4, Feb 15, 2006 IP
  3. mariush

    mariush Peon

    Messages:
    562
    Likes Received:
    44
    Best Answers:
    0
    Trophy Points:
    0
    #3
    Try adding image verification to the posts, one that would appear for example once every 3-5 posts ( in order to not upset people). A good tutorial is available here : http://www.phpnoise.com/tutorials/1/1

    Or, you could randomly switch fields in the form or change their name. This way a bot would fill the e-mail address incorectly and you can ignore the message.
     
    mariush, Feb 15, 2006 IP
  4. mad4

    mad4 Peon

    Messages:
    6,986
    Likes Received:
    493
    Best Answers:
    0
    Trophy Points:
    0
    #4
    Can you check the user agent or IP address of the bot? If so you could ban it that way.
     
    mad4, Feb 15, 2006 IP
  5. CanaryWoolf

    CanaryWoolf Peon

    Messages:
    114
    Likes Received:
    1
    Best Answers:
    0
    Trophy Points:
    0
    #5
    the script seems to work well and chucks out the error message - but how do how can I amend the mailing script so that it only posts the message if '$findme' was not found?
     
    CanaryWoolf, Feb 15, 2006 IP
  6. wwm

    wwm Peon

    Messages:
    308
    Likes Received:
    10
    Best Answers:
    0
    Trophy Points:
    0
    #6
    be smart take in the posters ip address, if u really hate them spam them back into oblivion

    fight fire with fire
     
    wwm, Feb 15, 2006 IP
  7. mad4

    mad4 Peon

    Messages:
    6,986
    Likes Received:
    493
    Best Answers:
    0
    Trophy Points:
    0
    #7
    Insert the entire mailing script where it says echo "OK";
     
    mad4, Feb 15, 2006 IP
  8. CanaryWoolf

    CanaryWoolf Peon

    Messages:
    114
    Likes Received:
    1
    Best Answers:
    0
    Trophy Points:
    0
    #8
    Great that works a treat - one final question:

    How do I insert multiple values for $findme = 'viagra';
     
    CanaryWoolf, Feb 15, 2006 IP
  9. mad4

    mad4 Peon

    Messages:
    6,986
    Likes Received:
    493
    Best Answers:
    0
    Trophy Points:
    0
    #9
    Run it a few times eg

    
    $findme  = 'viagra';
    $pos = strpos($filestring, $findme);
    $findme  = 'drugs';
    $pos = strpos($filestring, $findme);
    $findme  = 'cialis';
    $pos = strpos($filestring, $findme);
    
    PHP:
    Then if any of these match $pos will be true and the script will not run.
     
    mad4, Feb 15, 2006 IP
  10. CanaryWoolf

    CanaryWoolf Peon

    Messages:
    114
    Likes Received:
    1
    Best Answers:
    0
    Trophy Points:
    0
    #10
    Nope - it doesn't like that!

    Any other suggestion? (is there a way of including more words in one line?)
     
    CanaryWoolf, Feb 15, 2006 IP
  11. mad4

    mad4 Peon

    Messages:
    6,986
    Likes Received:
    493
    Best Answers:
    0
    Trophy Points:
    0
    #11
    
    $findme  = 'viagra';
    $pos1 = strpos($filestring, $findme);
    $findme  = 'drugs';
    $pos2 = strpos($filestring, $findme);
    $findme  = 'cialis';
    $pos3 = strpos($filestring, $findme); 
    
    if (($pos1 === false)&&($pos2 === false )&&($pos3 === false)){
    //run the script
    } 
    else
    {
    //error
    }
    
    PHP:
     
    mad4, Feb 15, 2006 IP
  12. CanaryWoolf

    CanaryWoolf Peon

    Messages:
    114
    Likes Received:
    1
    Best Answers:
    0
    Trophy Points:
    0
    #12
    Thanks that works ok but the error message returnsthe last $findme item as the bad string regardless of the bad string entered.

    A 'get-around' would be to enter some more generic text for the error message something like Banned words include sexually explicit language, reference to drugs etc. but if it could be automated that would be great.

    The complete code used is now:
    
    <?php
    $filestring="$_POST[sender_name] $_POST[message]";
    $findme  = 'viagra';
    $pos1 = strpos($filestring, $findme);
    $findme  = 'drugs';
    $pos2 = strpos($filestring, $findme);
    $findme  = 'cialis';
    $pos3 = strpos($filestring, $findme);  
    if (($pos1 === false)&&($pos2 === false )&&($pos3 === false)){
    
      $to = "info@emailaddress.com";			
    				//mail string
    				$msg = "Enquiry from\t$_POST[page]\n";
    				$msg .= "Name:\t$_POST[sender_name]\n";
    				$msg .= "E-mail:\t$_POST[sender_email]\n";
    				$msg .= "Telephone:\t$_POST[telephone]\n";
    				$msg .= "Company:\t$_POST[company]\n";
    				$msg .= "Message:\t$_POST[message]\n";
    				//set up e-mail
    				$subject = "Message from website\n";
    				$mailheaders = "From:\t$_POST[sender_email]\n";
    				$mailheaders .= "Reply to:\t$_POST[sender_email]";
    				//send mail
    				mail($to, $subject, $msg, $mailheaders);
    				echo "<strong>Thank you\t$_POST[sender_name] for your message. We will get in touch with you shortly.</strong>";
    
    } else { 
      echo "Sorry the string <strong>'$findme'</strong> was found in your message and has not been sent.<br /><br />Please resubmit or call xxxx xxxxxx"; 
      } 
    
    ?>
    
    
    PHP:
     
    CanaryWoolf, Feb 15, 2006 IP
  13. ian_ok

    ian_ok Peon

    Messages:
    551
    Likes Received:
    11
    Best Answers:
    0
    Trophy Points:
    0
    #13
    This is what I do, it stopped the email form injections.
    function validate_fields($s) {
      $forbidden = array('%', ',', ';', ':', '\r', '\n', '@acertaindomain.com');
      foreach ($forbidden as $f)
        if (strpos($s, $f) !== false) return false;
      return true;
    }
    Code (markup):
    and then:
    if (!validate_fields($_POST['email_address'])) {
      echo "<h4>Sorry you have entered an invalid character in your email address, you entered:</h4>";
      echo "<h4>$from</h4>";
      echo "<h4>The following characters are not permitted.</h4>";
      echo "<h4>&nbsp; %&nbsp;  ,&nbsp;  ;&nbsp;  :&nbsp;    \ </h4>";
      echo "<h4>Please check and try again</h4>";
      echo "<a href='javascript:history.back(1);'>Click here to return</a>";
      echo "<h4>This has been introduced to prevent automated robots hacking the email form</h4>";
    }
    Code (markup):
    You can also write th data to a file and check through a later stage just in case a SAFE user put in something they shouldn't nad then didn't bother to change it!

    Don't forget it's a ROBOT not a human doing this!

    Ian
     
    ian_ok, Feb 16, 2006 IP
  14. CanaryWoolf

    CanaryWoolf Peon

    Messages:
    114
    Likes Received:
    1
    Best Answers:
    0
    Trophy Points:
    0
    #14
    I've found another solution the solution and it is really logical. The one common thread on these spammers is that they try to include HTML code (the a href links) so we only need to ban the </a>

    The final code is:

    
    
    <?php
    $filestring="$_POST[sender_name] $_POST[message]";
    $findme = '</a>';
    $pos1 = strpos($filestring, $findme);
    $findme = '< / a>';
    $pos2 = strpos($filestring, $findme);
    
    if (($pos1 === false)&&($pos2 === false )){
    $to = "name@emailaddress.com"; 
    
    //mail string
    $msg = "Enquiry from\t$_POST[page]\n";
    $msg .= "Name:\t$_POST[sender_name]\n";
    $msg .= "E-mail:\t$_POST[sender_email]\n";
    $msg .= "Telephone:\t$_POST[telephone]\n";
    $msg .= "Company:\t$_POST[company]\n";
    $msg .= "Message:\t$_POST[message]\n";
    
    //set up e-mail
    $subject = "Message from website\n";
    $mailheaders = "From:\t$_POST[sender_email]\n";
    $mailheaders .= "Reply to:\t$_POST[sender_email]";
    
    //send mail
    mail($to, $subject, $msg, $mailheaders);
    
    echo "<strong>Thank you\t$_POST[sender_name] for your message. We will get in touch with you shortly.</strong>";
    
    } else { 
    
    echo "Sorry the string <strong>'$findme'</strong> was found in your message and has not been sent.<br /><br />Please resubmit or call xxxx xxxxxx"; 
    } 
    
    ?> 
    PHP:
    The second $findme = '< / a>'; is in there because it will always display the last 'word' and it ignores the correct formatting of the html tag </a> (it simply displays ''

    It works a treat!
     
    CanaryWoolf, Feb 16, 2006 IP