Prevent Mail Injection - mail()

Discussion in 'PHP' started by Lordo, Feb 17, 2006.

  1. #1
    One of my sites was suddenly suspended last week and the host forwarded the SPAM email message that was reported. It was an ad for some site that I don't know. The FROM email does not exist on my domain! I have never sent SPAM. :confused:

    Anyway, I googled the issue until I found the user contributed notices here:
    http://www.php.net/mail
    And I figured it out. Spammers sent SPAM via the mail form on my site and, additionally, caused it to be suspended. :mad:

    I read the whole contributions and started testing. I was lucky because the spammer was still online sending ads through my form! So, I could quickly know what he types and how he does that. Also, I knew how to permenantly stop him. :cool:

    So, if you have a mail form on your site, I strongly recommend that you add the following lines before sending the email:

    	$err = 0;
    	foreach($_POST as $val){
    	if(eregi("Content-Type",$val)) $err = 1;
    	}
    	
    	if($err == 1){
    	// SPAM - Don't send
    	
    	}
    	else{
    	// Clean - Send message now
    	
    	}
    PHP:
    I contacted the host again and explained the issue. They wanted me to switch to a safe CGI script but when they checked my lines and the result, they appreciated it. :)

    Hope that helps somebody.
     
    Lordo, Feb 17, 2006 IP
    Colleen likes this.
  2. dkalweit

    dkalweit Well-Known Member

    Messages:
    520
    Likes Received:
    35
    Best Answers:
    0
    Trophy Points:
    150
    #2
    As I read your code, all it'll do is prevent the spammer from using content-type headers. They could still send plain text spam, can't they?


    --
    Derek
     
    dkalweit, Feb 17, 2006 IP
  3. Lordo

    Lordo Well-Known Member

    Messages:
    2,082
    Likes Received:
    58
    Best Answers:
    0
    Trophy Points:
    190
    #3
    The issue is not preventing spammers from sending HTML messages. It is preventing them from passing "content-type" because it is vital for their business. In other words, if you prevent spammers from typing that tem, they won't be able to utilize your form for sending SPAM.

    I reached at this result after like 2 hours of playing vs. Mr. Spammer :) Tried many many things before making sure that this simple method stopped him.
     
    Lordo, Feb 17, 2006 IP
  4. Perrow

    Perrow Well-Known Member

    Messages:
    1,306
    Likes Received:
    78
    Best Answers:
    0
    Trophy Points:
    140
    #4
    Perrow, Feb 17, 2006 IP
  5. Lordo

    Lordo Well-Known Member

    Messages:
    2,082
    Likes Received:
    58
    Best Answers:
    0
    Trophy Points:
    190
    #5
    Thanks, Perrow, for the site.
    What I had was the second type. And I tried the first type on my site now but it didn't work. So, I believe my small code is a good solution.
     
    Lordo, Feb 17, 2006 IP
  6. clancey

    clancey Peon

    Messages:
    1,099
    Likes Received:
    63
    Best Answers:
    0
    Trophy Points:
    0
    #6
    Preventing these problems requires that you check all the input in the form before sending the email message.

    Step one is to make sure YOU define who the recipient is. I prefer to place that information outside the script. I do not want any accidental displays.

    Step TWO is to defang ALL user input.

    Email addresses should always be checked against a list of acceptable characters and unacceptable ones transformed into a benign state before they are used. This will kill the cc trick mentioned in the mail injection advice linked to by Perrow.

    The only characters i allow in email addreses are: '-a-zA-Z0-9_.@' I turn everything else into an underscore character.

    A similar, though less restrictive appraoch to subject lines and message contents prevents you from doing more than you intend when you redisplay email fields back to the user. You do not want to display back a command which somehow gets executed!

    When scripts are written -- security comes first.

    I learned to define input in the old pre-internet days when using xBase backended BBS systems. And, to make sure key board combinations were intercepted an neutralized so someone could not crasjh the BBS and gain access to the command line.

    The same concepts apply today.
     
    clancey, Feb 17, 2006 IP
  7. ruby

    ruby Well-Known Member

    Messages:
    1,854
    Likes Received:
    40
    Best Answers:
    1
    Trophy Points:
    125
    #7
    I use visual verify codes on pages like this (Contact Us) so that the user needs to enter the random code for the action to be successful.
     
    ruby, Apr 1, 2007 IP
  8. TommyD

    TommyD Peon

    Messages:
    1,397
    Likes Received:
    76
    Best Answers:
    0
    Trophy Points:
    0
    #8
    I think you missed the point. You are trying to prevent spiders/programs from contacting you. The Op is looking to prevent people hijacking contact us forms and spamming people.

    tom
     
    TommyD, Apr 1, 2007 IP
  9. ruby

    ruby Well-Known Member

    Messages:
    1,854
    Likes Received:
    40
    Best Answers:
    1
    Trophy Points:
    125
    #9
    Yes and that can be done using a visual verify code, as well as good coding techniques.
     
    ruby, Apr 1, 2007 IP
  10. Lordo

    Lordo Well-Known Member

    Messages:
    2,082
    Likes Received:
    58
    Best Answers:
    0
    Trophy Points:
    190
    #10
    ruby: capcha will not stop mail injection (people sending spam to OTHERS on your behalf - from your form). It will only stop bots from using your form to send YOU spam.
     
    Lordo, Apr 1, 2007 IP
  11. ruby

    ruby Well-Known Member

    Messages:
    1,854
    Likes Received:
    40
    Best Answers:
    1
    Trophy Points:
    125
    #11
    Yes I know this but it makes it more of a pain as they cant automate it and send thousands! They bascially cant hijack your form and send thousands and thousands one after the other. Each time they need to enter the code.

    Thats all I meant.
     
    ruby, Apr 2, 2007 IP
  12. Lordo

    Lordo Well-Known Member

    Messages:
    2,082
    Likes Received:
    58
    Best Answers:
    0
    Trophy Points:
    190
    #12
    I see your point. Still you have to prorammatically take care of the issue, right? :)
     
    Lordo, Apr 2, 2007 IP
  13. ruby

    ruby Well-Known Member

    Messages:
    1,854
    Likes Received:
    40
    Best Answers:
    1
    Trophy Points:
    125
    #13
    Absolutely!
     
    ruby, Apr 2, 2007 IP
  14. webdude12

    webdude12 Peon

    Messages:
    5
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #14
    This isnt 100%, but first, do not use standard variable names in your mail() script, change the send_to address to something like $send_to_now and dont set it in the html code, set it as a hard variable in the php code.

    Also I use this code to make sure the mail script isnt being called by another domain:

    
    $form_url_array = parse_url($form_url);
    $form_domain = $form_url_array[host];
    if($form_domain != $HTTP_SERVER_VARS[HTTP_HOST]) {
    echo "<h2>Form Error - Invalid Domain</h2>
    You have accessed this script from an external domain - this is not allowed.<br>
    Your IP address has been logged and flagged.
    <br><br>";
    $error = "yes";
    }
    
    Code (markup):
    While I dont actually log the IP address, figured it might scare a few of the beginner script kiddies. :)
     
    webdude12, Apr 3, 2007 IP
  15. KlearConcepts

    KlearConcepts Peon

    Messages:
    349
    Likes Received:
    2
    Best Answers:
    0
    Trophy Points:
    0
    #15
    maybe you can also stop html tags or anything like that?

    
    $from = strip_tags(htmlentites($_POST['from']));
    
    PHP:
     
    KlearConcepts, Apr 4, 2007 IP