Results 1 to 23 of 23
  1. #1
    Join Date
    Sep 2004
    Posts
    74

    Help me secure this php sendmail script?

    Hello,

    I've run a dedicated server for over a year now, and I received an email from SpamCop saying somebody dobbed me in for spamming.

    It would appear somebody has worked out how to spam via one of my customers sendmail scripts.

    Here's the script:

    Code:
    <?
     
    $body = "
    Name:       ".$_POST["name"]."
    Company:    ".$_POST["company"]."
    Position:   ".$_POST["position"]."
    Email:      mailto:".$_POST["email"]."
    Phone:      ".$_POST["phone"]."
     
    Comments:
    ".$_POST["message"];
     
    mail( "[email protected]", "Contact from www.mycustomer.com - ".$_POST["company"], $body, "From: ".$_POST["name"]."
    <".$_POST["email"].">");
     
    header( "Location: ../thanks/" ); 
    ?>
    They seem to have done it via the BCC field, here's the headers from the actual mail:

    [code]

    To: x
    Subject: Contact from www.mycustomer.com -
    From: [email protected]
    Content-Type: text/plain; charset=\"us-ascii\"
    MIME-Version: 1.0
    Content-Transfer-Encoding: 7bit
    Subject: Could you stand to lose 10-15 pounds of fat?
    Message-Id: <[email protected]>
    Date: Tue, 29 Nov 2005 05:54:22 +1100
    Name: state
    Content-Type: text/plain; charset=\"us-ascii\"
    MIME-Version: 1.0
    Content-Transfer-Encoding: 7bit
    Subject: Could you stand to lose 10-15 pounds of fat?
    bcc: [email protected], [email protected], [email protected],
    [email protected], [email protected], [email protected],
    [email protected], [email protected], [email protected],
    /code]

    The BCC list keeps going - I guess that's what they are using.

    Can anybody see what's wrong with this script? This is the first instance of spamming I've had.

  2. #2
    Join Date
    Aug 2000
    Location
    Sheffield, South Yorks
    Posts
    3,480
    You need to check:

    $_POST['name'] and $_POST['email']

    in your case, they will be inserting carriage returns in it, then setting the BCC field. You need to strip \n and \r from it, as well as check for the bcc field being set and remove it.
    Karl Austin :: KDA Web Services Ltd.
    UK Business Hosting and Managed Servers - Hosting for Business Users :: 0800 5429 764
    Call us today and ask about our hosting solutions.

  3. #3
    Join Date
    Aug 2000
    Location
    Sheffield, South Yorks
    Posts
    3,480
    On 2nd look, you also need to check $_POST['company'] for the same as well.
    Karl Austin :: KDA Web Services Ltd.
    UK Business Hosting and Managed Servers - Hosting for Business Users :: 0800 5429 764
    Call us today and ask about our hosting solutions.

  4. #4
    Personally, I would place the script in a directory outside the web root. That should ensure that they can't post to it

  5. #5
    Join Date
    Aug 2000
    Location
    Sheffield, South Yorks
    Posts
    3,480
    Quote Originally Posted by 123sell
    Personally, I would place the script in a directory outside the web root. That should ensure that they can't post to it
    I'm sorry, but how does that make it secure? Presumably the user actually wants to be able to use their script? Even if they include it from another script, the security issues will still be there and exploitable.
    Karl Austin :: KDA Web Services Ltd.
    UK Business Hosting and Managed Servers - Hosting for Business Users :: 0800 5429 764
    Call us today and ask about our hosting solutions.

  6. #6
    I think sell123 means making a form and separating the PHP script into another file that you put below the web root. Then in the form, just do a POST ACTION to the PHP file below the web root and a header refresh to a thank you page. That way you can avoid the include. That's at least how it was recommended to us...
    Last edited by mpoulsen; 11-30-2005 at 08:02 AM.
    MP Hosting
    http://mphosting.net

  7. #7
    Join Date
    Aug 2000
    Location
    Sheffield, South Yorks
    Posts
    3,480
    How on earth can you do a POST request to a file that isn't in a web accessible folder? At the end of the day, the code above has as many holes as a block of swiss cheese, it needs securing - Security by obscurity (which wouldn't work anyway) does not count.
    Karl Austin :: KDA Web Services Ltd.
    UK Business Hosting and Managed Servers - Hosting for Business Users :: 0800 5429 764
    Call us today and ask about our hosting solutions.

  8. #8
    I dunno... I never actually did it :-) That's just how it was explained to me...
    MP Hosting
    http://mphosting.net

  9. #9
    How about this code? Is this considered secure?

    <?php
    class clsMail
    {
    var $to;
    var $from;
    var $cc;
    var $bcc;
    var $subject;
    var $message;
    var $contentType;

    function clsMail() //init
    {
    $this->to = "";
    $this->from = "";
    $this->cc = "";
    $this->bcc = "";
    $this->subject = "";
    $this->message = "";
    $this->contentType = "html"; // text, html
    }

    function isemail($email)
    {
    // regx to test for valid e-mail adres
    $regex = '^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]{2,})+$';
    if (eregi($regex, $email)) return true;
    else return false;
    }

    function send()
    {
    // check if e-mail adresses are valid.
    if (!clsMail::isemail($this->to)) die('ERROR: Invalid To e-mail adres');
    if (!clsMail::isemail($this->from)) die('ERROR: Invalid From e-mail adres');
    if (!clsMail::isemail($this->cc) && !$this->cc=="") die('ERROR: Invalid CC e-mail adres');
    if (!clsMail::isemail($this->bcc) && !$this->bcc=="") die('ERROR: Invalid BCC e-mail adres');

    // To send HTML mail, you can set the Content-type header. html is the default
    $headers = "MIME-Version: 1.0\r\n";
    if ($this->contentType=="html") $headers .= "Content-type: text/html; charset=iso-8859-1\r\n";
    else $headers .= "Content-type: text/plain; charset=us-ascii\r\n";

    // additional headers for From, Cc and Bcc
    $headers .= "From: ".$this->from."\r\n";
    if (!$this->cc=="") $headers .= "Cc: ".$this->cc."\r\n";
    if (!$this->bcc=="") $headers .= "Bcc: ".$this->bcc."\r\n";

    // send the e-mail
    return mail($this->to, $this->subject, $this->message, $headers);
    }

    }

    // example how te use the mail class
    $this = new clsMail();
    $this->to="[email protected]";
    $this->from="[email protected]";
    $this->subject="Test";
    $this->message="Test Message";
    echo $this->send(); // returns true or false at failure
    ?>
    MP Hosting
    http://mphosting.net

  10. #10
    Join Date
    Aug 2000
    Location
    Sheffield, South Yorks
    Posts
    3,480
    Nope, it isn't secure either, as it doesn't do any checking on the subject line - Which gets added to the mail headers, so is a perfect place to add a BCC in. https://nms-cgi.sourceforge.net - Nice secure formmail.
    Karl Austin :: KDA Web Services Ltd.
    UK Business Hosting and Managed Servers - Hosting for Business Users :: 0800 5429 764
    Call us today and ask about our hosting solutions.

  11. #11
    Thanks for the link... I am looking for something to suggest to those of our customers who wants to program themselves - and of course something that fang666 can use as well.

    To secure the subject of the example code, can that not just be done with adding this?

    if (!clsMail::isemail($this->subject)) die('ERROR: Invalid Subject');
    MP Hosting
    http://mphosting.net

  12. #12
    Join Date
    Aug 2000
    Location
    Sheffield, South Yorks
    Posts
    3,480
    Only if you want the subject to be valid if it contains an email address.
    Karl Austin :: KDA Web Services Ltd.
    UK Business Hosting and Managed Servers - Hosting for Business Users :: 0800 5429 764
    Call us today and ask about our hosting solutions.

  13. #13
    Join Date
    Sep 2004
    Posts
    74
    Thanks for all your replies. I do appreciate it.

    THe actual contact form is somewhere else, and its form action is this particular file.

    I'll make the suggestion that they only include the POST data in the body of the email, leaving the TO and SUBJECT & headers all made up on the spot, that should do it.

  14. #14
    Join Date
    Dec 2005
    Location
    Florence, AL
    Posts
    17
    Here's code we use to check for bcc, content-type, and mime-version in our PHP contact forms:

    PHP Code:
    foreach ( $_POST as $key => $value ) {
    if ( 
    stristr$value"bcc:" ) ) { echo "Sorry, we do not allow bcc: in the form."; exit; }
    if ( 
    stristr$value"content-type:" ) ) { echo "Sorry, we do not allow content-type: in the form."; exit; }
    if ( 
    stristr$value"mime-version:" ) ) { echo "Sorry, we do not allow mime-version: in the form."; exit; }

    This will sanatize each field in POST, not just certain ones. This makes it more flexible and easier to add future fields.

    Also note that the script dies with a simple error message. I feel its better to do this then waste resources rendering a nice page (possibly with SQL calls and the like) to a spammer. The odds of a legitimate posting with those fields are next to nil.

    Hope this helps someone.
    Robert Oliver
    OCS Solutions - Web Hosting and Development
    Ruby Forums - Discuss Ruby and Ruby on Rails!
    Phone: 1-800-672-8415, Skype: ocssolutions

  15. #15
    Join Date
    Aug 2000
    Location
    Sheffield, South Yorks
    Posts
    3,480
    Still not secure I'm afraid, you need to check for to and cc fields as well.
    Karl Austin :: KDA Web Services Ltd.
    UK Business Hosting and Managed Servers - Hosting for Business Users :: 0800 5429 764
    Call us today and ask about our hosting solutions.

  16. #16
    Join Date
    Dec 2005
    Location
    Florence, AL
    Posts
    17
    Good point. Thanks KDAWebServices. Although, we never ran into SPAM form problems with CC's, only BCC's and such, that makes a good addition.

    Here's the updated code then:

    PHP Code:
    foreach ( $_POST as $key => $value ) {
    if ( 
    stristr$value"cc:" ) ) { echo "Sorry, we do not allow cc: in the form."; exit; }
    if ( 
    stristr$value"bcc:" ) ) { echo "Sorry, we do not allow bcc: in the form."; exit; }
    if ( 
    stristr$value"content-type:" ) ) { echo "Sorry, we do not allow content-type: in the form."; exit; }
    if ( 
    stristr$value"mime-version:" ) ) { echo "Sorry, we do not allow mime-version: in the form."; exit; }

    Robert Oliver
    OCS Solutions - Web Hosting and Development
    Ruby Forums - Discuss Ruby and Ruby on Rails!
    Phone: 1-800-672-8415, Skype: ocssolutions

  17. #17
    Join Date
    Dec 2005
    Location
    Florence, AL
    Posts
    17
    Oh, I missed the to: part, but we don't ever take those as post vars. Those are always taken from a config file, database value, or hardcoded into the script.
    Robert Oliver
    OCS Solutions - Web Hosting and Development
    Ruby Forums - Discuss Ruby and Ruby on Rails!
    Phone: 1-800-672-8415, Skype: ocssolutions

  18. #18
    Join Date
    Aug 2000
    Location
    Sheffield, South Yorks
    Posts
    3,480
    You still have to check that spammers aren't adding them in though, if they add another to: header in, then there's a chance it'll overide the one you've set.
    Karl Austin :: KDA Web Services Ltd.
    UK Business Hosting and Managed Servers - Hosting for Business Users :: 0800 5429 764
    Call us today and ask about our hosting solutions.

  19. #19
    Join Date
    Dec 2005
    Location
    Florence, AL
    Posts
    17
    If you hard code the "to" address into the mail function, you will be OK.
    Robert Oliver
    OCS Solutions - Web Hosting and Development
    Ruby Forums - Discuss Ruby and Ruby on Rails!
    Phone: 1-800-672-8415, Skype: ocssolutions

  20. #20
    Join Date
    Aug 2000
    Location
    Sheffield, South Yorks
    Posts
    3,480
    No you won't, not if the spammer uses an unchecked field that goes in the headers.
    Karl Austin :: KDA Web Services Ltd.
    UK Business Hosting and Managed Servers - Hosting for Business Users :: 0800 5429 764
    Call us today and ask about our hosting solutions.

  21. #21
    Join Date
    Dec 2005
    Location
    Florence, AL
    Posts
    17
    I'll have to respectfully disagree. Tests we've conducted prove otherwise.

    Besides, on all of these contact forms, if it was simple enough just to put a To: in the post and that overrides the mail ( "[email protected] address, you'd think our forms would have been compromised already.

    Additionally, the only possible room for a To: to fit in would be in the From: part of the additional headers field (the 4th arg in mail() ), which we validate with a regex anyway. There is just no way I'm aware of using the code I pasted an a From: email regex validation which all forms should have anyway for a To: to find its way into the headers.
    Robert Oliver
    OCS Solutions - Web Hosting and Development
    Ruby Forums - Discuss Ruby and Ruby on Rails!
    Phone: 1-800-672-8415, Skype: ocssolutions

  22. #22
    Join Date
    Aug 2000
    Location
    Sheffield, South Yorks
    Posts
    3,480
    I wish people would learn to read before they post, which part of "not if the spammer uses an unchecked field that goes in the headers." did you not understand to say that the spammer would have to put a to: into a field that goes into the email headers that has been left unchecked? Where did I say you could just put it in the body of the email?
    Karl Austin :: KDA Web Services Ltd.
    UK Business Hosting and Managed Servers - Hosting for Business Users :: 0800 5429 764
    Call us today and ask about our hosting solutions.

  23. #23
    Join Date
    Dec 2005
    Location
    Florence, AL
    Posts
    17
    I don't want to get into any heated discussions about it. I just hope the original poster was helped by our conversation.

    Good luck mpoulsen, and if you have any future problems with the script I'm sure we'll be glad to help!
    Robert Oliver
    OCS Solutions - Web Hosting and Development
    Ruby Forums - Discuss Ruby and Ruby on Rails!
    Phone: 1-800-672-8415, Skype: ocssolutions

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •