Script to do a form submition to e-mail.

Discussion in 'PHP' started by Josh Inno, Jan 2, 2007.

  1. #1
    Hello there.

    Until recently we were using a free script on our client's site to generate form submissions to send e-mails to our clients. However spammers were apparently able to exploit the code to send spam from our server. I was hoping to get some help either finding a new free code without that exploit vulnerability, or some help setting up a script without that exploit in it.
     
    Josh Inno, Jan 2, 2007 IP
  2. clancey

    clancey Peon

    Messages:
    1,099
    Likes Received:
    63
    Best Answers:
    0
    Trophy Points:
    0
    #2
    Since spammers come in the robotic and the human variety, the techniques and strategies needed to combat use of scripts as spam are multi-leveled.

    Consequently, a determined spammer will always get through especially in they can fill in the form and do some kind of bulk send to your customers.

    If you are determined to maintain that capability, then you need to make sure only registered users can use the facility. Use a captcha image in the registration process to defeat nearly all robots.

    Secondly, implement an approval system before people can join and then send out emails to other people.

    If it is a forum, users might need to accumulate a certain number of positive feedbacks for contributions to forums and/or have made a certain minimum number of posts before they can contact other people or include any sort of URL in postings.

    If it is not a forum, but a type of "trade leads" utility, then I would require admin approval of all accounts before they can use the facility. The information provided will help you prevent 90% of the potential human spammers from doing any damage to you and your site's reputation.

    In my case, I once used a trade leads type form, but you needed to be a paying customer to access the page. And the content of the email message was predefined by tick boxes in the form. However, I once had a spammer register and then phone to ask how much I would charge for my customer list.

    Make sure the form needs to be called via another page. Never allow direct access. In PHP, the calling page can define a variable, which must be set to get the the form to display.

    The indedx page might start with the line:

    define( '_VALID_DEF', 1 );

    and the form script starts with the line:

    defined( '_VALID_DEF' ) or die( 'Unexpected server problems' );
     
    clancey, Jan 2, 2007 IP
  3. Josh Inno

    Josh Inno Guest

    Messages:
    1,623
    Likes Received:
    14
    Best Answers:
    0
    Trophy Points:
    0
    #3
    I'm sorry, I guess I was unclear with our particular circumstances.

    We have a Dentist as a customer who wants a particular feature on his site. He wants to have a contact form on the website, which will allow customers to send e-mails to his office from his website, in regards to their symptoms, and setting up an appointment (rather than publishing his e-mail address on the website).

    I was given a copy of a free php script by a co-worker who had used it on sites they had done the same for in the past. Unfortunately I heard back from her today that the code she used had been exploited on one of those sites in order to send spam messages to thousands of people, even though the recipient of the form was specifically set in the code.

    I understand that, aside from captcha, there's little we can do to prevent spam to our client, but at least it's a bit better than publishing their email address on the website. However I'd like to try to find a form script, or get help building one, that will not allow spammers to use our servers to send out bulk e-mail to thousands of people.
     
    Josh Inno, Jan 2, 2007 IP
  4. krakjoe

    krakjoe Well-Known Member

    Messages:
    1,795
    Likes Received:
    141
    Best Answers:
    0
    Trophy Points:
    135
    #4
    post the code I'll fix it ....don't want any html, just php
     
    krakjoe, Jan 2, 2007 IP
  5. Josh Inno

    Josh Inno Guest

    Messages:
    1,623
    Likes Received:
    14
    Best Answers:
    0
    Trophy Points:
    0
    #5
    Here's the php back end side of things.

    Also, if you can explain why the fix works, I would definitely appreciate it.

    
    <?php
    // Website Contact Form Generator 
    // http://www.tele-pro.co.uk/scripts/contact_form/ 
    // This script is free to use as long as you  
    // retain the credit link  
    
    // get posted data into local variables
    $EmailFrom = Trim(stripslashes($_POST['EmailFrom'])); 
    $EmailTo = "pioneergreensdds@alltell.net";
    $Subject = "Website Contact";
    $Name = Trim(stripslashes($_POST['Name'])); 
    $Address = Trim(stripslashes($_POST['Address'])); 
    $Telephone = Trim(stripslashes($_POST['Telephone'])); 
    $Mobile = Trim(stripslashes($_POST['Mobile'])); 
    $NatureofComplaint = Trim(stripslashes($_POST['NatureofComplaint'])); 
    
    // validation
    $validationOK=true;
    if (Trim($EmailFrom)=="") $validationOK=false;
    if (!$validationOK) {
      print "<meta http-equiv=\"refresh\" content=\"0;URL=error.htm\">";
      exit;
    }
    
    // prepare email body text
    $Body = "";
    $Body .= "Name: ";
    $Body .= $Name;
    $Body .= "\n";
    $Body .= "Address: ";
    $Body .= $Address;
    $Body .= "\n";
    $Body .= "Telephone: ";
    $Body .= $Telephone;
    $Body .= "\n";
    $Body .= "Mobile: ";
    $Body .= $Mobile;
    $Body .= "\n";
    $Body .= "NatureofComplaint: ";
    $Body .= $NatureofComplaint;
    $Body .= "\n";
    
    // send email 
    $success = mail($EmailTo, $Subject, $Body, "From: <$EmailFrom>");
    
    // redirect to success page 
    if ($success){
      print "<meta http-equiv=\"refresh\" content=\"0;URL=ok.htm\">";
    }
    else{
      print "<meta http-equiv=\"refresh\" content=\"0;URL=error.htm\">";
    }
    ?>
    
    Code (markup):
     
    Josh Inno, Jan 2, 2007 IP
  6. Barti1987

    Barti1987 Well-Known Member

    Messages:
    2,703
    Likes Received:
    115
    Best Answers:
    0
    Trophy Points:
    185
    #6
    Chances are that they are not actually using your server, rather just the domain name.

    Check the IPs of the sender to check if it matches your server's IP.

    Peace,
     
    Barti1987, Jan 3, 2007 IP
  7. clancey

    clancey Peon

    Messages:
    1,099
    Likes Received:
    63
    Best Answers:
    0
    Trophy Points:
    0
    #7
    I was working on a modifiction to your script and I lost my way. It might be possible to inject additional header information into your script as part of the user submitted email address. By adding a bcc line, their submitted email could be blasted around the web. You need to ensure that this cannot happen by sanitizing user submitted information. I would add the following:

    
    $validationOK=true;
    if (Trim($EmailFrom)=="") $validationOK=false;
    if( $EmailFrom != sanitizeMail($EmailFrom) ) $validationOK=false;
    
     
    
    function sanitizeMail( $text)
    { 
    if(!$text) { return $text; }
    
    $OK_CHARS='\-a-zA-Z0-9_.\@';
    $text = preg_replace( "/[^$OK_CHARS]/", "_", $text);
    
    return $text;
    }
    
    PHP:
     
    clancey, Jan 4, 2007 IP
  8. Josh Inno

    Josh Inno Guest

    Messages:
    1,623
    Likes Received:
    14
    Best Answers:
    0
    Trophy Points:
    0
    #8
    Thank you. I was actually able to find information about the bcc insert while cruising the web for information. I've already got a function to kill newlines, and one to block the submission if bad strings like "bcc:" are found.

    If possible, I'd rather not block out people who actually put in things like tildes and umlots over letters in their names, but your function does look like a simple, and useful one. Thank you.

    Just a note: it seems to block spaces.
     
    Josh Inno, Jan 8, 2007 IP
  9. Josh Inno

    Josh Inno Guest

    Messages:
    1,623
    Likes Received:
    14
    Best Answers:
    0
    Trophy Points:
    0
    #9
    Okay, there's a new problem. We're looking for a way where we can let the client get a copy of their e-mail that they are sending through the form, while keeping spammers from using this function to abuse our form.
     
    Josh Inno, Jan 8, 2007 IP
  10. JEET

    JEET Notable Member

    Messages:
    3,832
    Likes Received:
    502
    Best Answers:
    19
    Trophy Points:
    265
    #10
    I think all you need to do here is check if the email id submitted is a valid one (check for format), and perform your previous header injection check on the email field again. Then repeat the mail function...
    Bye :)
     
    JEET, Jan 8, 2007 IP
  11. Josh Inno

    Josh Inno Guest

    Messages:
    1,623
    Likes Received:
    14
    Best Answers:
    0
    Trophy Points:
    0
    #11
    Well the problem here is that we're letting the person specify an e-mail address to send the message too. Isn't that exactly what spammers are searching for in online forms to abuse?
     
    Josh Inno, Jan 8, 2007 IP
  12. glennhefley

    glennhefley Peon

    Messages:
    73
    Likes Received:
    3
    Best Answers:
    0
    Trophy Points:
    0
    #12
    The script you posted is pretty simplistic. No security and no hashing. The problem you are describing however doesn't seem to stem from this script. As was stated, they are probably using your server in another fashion and not through this PHP script specifically (though it very well could have given them the front door key to the other usage).

    From your description, the spammers have gotten a hold of your client list off the server. Damage done in that case. As simplistic as this code is, it is quite possible that they injected code to it which simply emailed them the client list. Again, there's no checking, security, rehash.. nothing.

    The basic ways of doing this are captcha, as you mentioned.

    The other methods include checking and verifying that the form was used, what site it was used from, how often it was used (stopping submission from the same source/ip for three minutes at a time for example) and other methods. Also making sure that the message is rendered inert... meaning it is not live code that may be ran by your server inside the script. (yes, that is quite possible and one of the more common hacks).

    I have to make one of these later on this week. I'll post the code here for you to use if you want when I'm finished (if my client doesn't object of course). However, bottom line is that either you use free source and take your chances, or hire a real programmer to develop these things for you.

    I would go with the professional on any system that allows access to your server. You probably don't need on for things like page displays and reports or anything of that nature, but if you are taking in information, and doing anything other than inputting that information straight into a database table, then the professional is probably a good idea. Cause we think of things like this and take them seriously.

    of course, professionals are a bit more expensive as well. In this case, probably much less expensive.
     
    glennhefley, Jan 8, 2007 IP
  13. Josh Inno

    Josh Inno Guest

    Messages:
    1,623
    Likes Received:
    14
    Best Answers:
    0
    Trophy Points:
    0
    #13
    I think that they just injected a BCC: code in order to abuse our server and bandwidth to mass-mail the same message. I spent about a day writing up an new form, and putting some security features in it.

    I've since instituted some measures including newline yanking, and checking for bad input like "bcc", I've also been given a bit of code that will make sure that a browser is used, and another one to strip html, and php code.

    I'm trying to decide between having the script and form pages split, or having them both on the same page.
     
    Josh Inno, Jan 8, 2007 IP
  14. JEET

    JEET Notable Member

    Messages:
    3,832
    Likes Received:
    502
    Best Answers:
    19
    Trophy Points:
    265
    #14
    That is why I suggested you perform your header injection checks on the email field again, and "then" and send the form.
    Bye :)
     
    JEET, Jan 9, 2007 IP
  15. pixel_perfect

    pixel_perfect Banned

    Messages:
    238
    Likes Received:
    2
    Best Answers:
    0
    Trophy Points:
    0
    #15
    HI,

    simple solution to your problem is use captcha image verification,

    and then spammer have to do it mannually and if the waste there whole day to do that then let them waste there time...
     
    pixel_perfect, Jan 9, 2007 IP
  16. Josh Inno

    Josh Inno Guest

    Messages:
    1,623
    Likes Received:
    14
    Best Answers:
    0
    Trophy Points:
    0
    #16
    *chuckles* I suppose I see your points. If I make them enter it into the field on the form, and do checking so that they can only send 1 at a time, that's about as good a protection as I can get for this feature.
     
    Josh Inno, Jan 9, 2007 IP