#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    24
    Rep Power
    0

    Mail function security


    Hi all.

    I have a php file below that inserts the end user's data into a table (DataEntryTable). Thanks to much help from Jacques on here I was able to add security to it, but I'm stuck in the mail() function part. I don't know how to add security to that portion.

    Any ideas on how I can make this portion of my script secure, starting with the line $lot = $_POST['lot'];?

    Thank you in advance!

    PHP Code:
    <?php 

           
    require("common.php");
        
       
        if (isset(
    $_SESSION['user'])){   // check session
         
          
    if (isset($_POST)) { 
               if (isset(
    $_POST['action_token']) && isset($_SESSION['action_token']) && $_POST['action_token'] == $_SESSION['action_token']) {      // check request token
         
                  
    $date = new DateTime();
                  
    $date->setTimezone(new DateTimeZone('America/New_York'));
                  
    $fdate $date->format('Y-m-d H:i:s');

            
    $query 
                INSERT INTO DataEntryTable ( 
                    BuilderCommunityID, 
                    Lot, 
                    Block,
                    Type,
                     Notes,
                    UserID,
                    CreateDate
                ) VALUES ( 
                    :buildercommunityid, 
                    :lot, 
                    :block,
                    :type,
                    :notes,
                    :userid,
                    :currentdatetime
                ) 
            "


               
            
    $query_params = array( 
                
    ':buildercommunityid' => $_POST['BuilderCommunity'], 
                
    ':lot' => $_POST['lot'], 
                
    ':block' => $_POST['block'], 
                
    ':type' =>$_POST['type'],
                
    ':notes' => $_POST['notes'],
                
    ':userid' => $_SESSION['user']['userid'] ,
                
    ':currentdatetime' => $fdate
            
    ); 
             
         
               
                
    $stmt $db->prepare($query); 
                
    $result $stmt->execute($query_params); 
     
      
     
    $lot $_POST['lot'];
     
    $block $_POST['block'];
     
    $notes $_POST['notes'];
     
     
    $smt $db->prepare('SELECT Builder, Community FROM BuilderTable   WHERE BuilderCommunityID =  :buildercommunityid ');
     
    $smt->execute(array(  ':buildercommunityid' => $_POST['BuilderCommunity']));
     
    $smt->bindColumn('Builder'$builder);
     
    $smt->bindColumn('Community'$community);
     
    $smt->fetch(PDO::FETCH_BOUND);
     
     
    $smt $db->prepare('SELECT Email FROM ProjectManagers INNER JOIN ProjectManagerAssignment ON ProjectManagerAssignment.ProjectManagerID = ProjectManagers.ProjectManagerID WHERE BuilderCommunityID = :buildercommunityid ');
     
    $smt->execute(array(  ':buildercommunityid' => $_POST['BuilderCommunity']));
     
    $smt->bindColumn('Email'$email);
     
     while (
    $row $smt->fetch(PDO::FETCH_BOUND)){
    $to $email;
    $subject "Notification";
    $from "aaa@abc.com";
    $body = <<<EOD
    <br><br>
    Builder: 
    $builder <br>
    Community: 
    $community <br>
    Lot:  
    $lot  <br>
    Block: 
    $block <br>
    Notes: 
    $notes <br>
    Date: 
    $fdate <br>
    EOD;
    $headers "From:" $from "\r\n";
    $headers .= "Content-type: text/html\r\n";
    mail($to,$subject,$body,$headers);
    }
             
            unset( 
    $_SESSION['action_token'] );
            
    header('Location: Menu.php');
            exit();
           }
          
           else {       
                echo 
    'invalid submission'
                
    trigger_error('possible CSRF attack'E_USER_ERROR);    
                exit; 
            } 
          
          }      
        } 
    ?>
  2. #2
  3. Web Developer/Musician
    Devshed Regular (2000 - 2499 posts)

    Join Date
    Nov 2004
    Location
    Tennessee Mountains
    Posts
    2,408
    Rep Power
    1031
    The rule of thumb with mail function security is to sanitize anything that goes in the headers first of all. There are some things you can do to the body of the message to check it for injection but the to, cc, bcc, subject data all have to be carefully filtered. Rather than me writing an article here about mail header injection, take a look at an existing article and filter the data accordingly. The attacks are not unlike SQL injection. The idea is to take what should be just data and add header code to it to add recvipients and alter the content of the message. The security goal is to ensure that what is supposed to be data (such as a sinlge email address) validates as an email address and not a long string of email addresses or other code. Lots of regex is usually involved.

    http://www.dreamincode.net/forums/to...er-injections/

    http://resources.infosecinstitute.com/email-injection/
    Last edited by Hammer65; August 29th, 2013 at 09:16 AM.
  4. #3
  5. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,957
    Rep Power
    1046
    Hi,

    the solution is to use a library and stop reinventing the wheel.

    And of course you must escape variables before you insert them into the HTML content -- just like everywhere else.
    The 6 worst sins of security ē How to (properly) access a MySQL database with PHP

    Why canít I use certain words like "drop" as part of my Security Question answers?
    There are certain words used by hackers to try to gain access to systems and manipulate data; therefore, the following words are restricted: "select," "delete," "update," "insert," "drop" and "null".
  6. #4
  7. Web Developer/Musician
    Devshed Regular (2000 - 2499 posts)

    Join Date
    Nov 2004
    Location
    Tennessee Mountains
    Posts
    2,408
    Rep Power
    1031
    PHP mailer is great. I've used it, in fact I would recommend using it over using the mail function by itself, but it doesn't offer mail injection protection. You will still have to do that yourself. I edited my post above to include links to information that you can use to get started.
  8. #5
  9. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,957
    Rep Power
    1046
    Originally Posted by Hammer65
    but it doesn't offer mail injection to protection.
    Not sure what version of PHPMailer you used, but they go through great length to make sure everything is secure and correct. Look at the code. Of course they cannot do magic. If you insert raw variables into the message, well, that's your fault.

    I strongly advice against fumbling with custom filters. You're almost guaranteed to get it wrong, forget something or whatever. Your first link actually starts with a broken filter.

    If I may quote the PHPMailer page:

    Originally Posted by https://github.com/PHPMailer/PHPMailer
    Formatting email correctly is surprisingly difficult. There are myriad overlapping RFCs, requiring tight adherence to horribly complicated formatting and encoding rules - the vast majority of code that you'll find online that uses the mail() function directly is just plain wrong! Please don't be tempted to do it yourself - if you don't use PHPMailer, there are many other excellent libraries that you should look at before rolling your own - try SwiftMailer, Zend_Mail, eZcomponents etc.
    The 6 worst sins of security ē How to (properly) access a MySQL database with PHP

    Why canít I use certain words like "drop" as part of my Security Question answers?
    There are certain words used by hackers to try to gain access to systems and manipulate data; therefore, the following words are restricted: "select," "delete," "update," "insert," "drop" and "null".
  10. #6
  11. Web Developer/Musician
    Devshed Regular (2000 - 2499 posts)

    Join Date
    Nov 2004
    Location
    Tennessee Mountains
    Posts
    2,408
    Rep Power
    1031
    Originally Posted by Jacques1
    Not sure what version of PHPMailer you used, but they go through great length to make sure everything is secure and correct. Look at the code. Of course they cannot do magic. If you insert raw variables into the message, well, that's your fault.

    I strongly advice against fumbling with custom filters. You're almost guaranteed to get it wrong, forget something or whatever. Your first link actually starts with a broken filter.

    If I may quote the PHPMailer page:
    None of the versions I have used address injection, just making sure that the message is fomatted properly. if you know regex well enough a custom filter will work fine. Validating whether or not an email address will work properly is not quite the same thing as making sure it's just an email and nothing else.

    It's been a while since I had to worry about this particular security issue but I don't know of any libraries which deal with it directly.

    Comments on this post

    • Jacques1 disagrees
  12. #7
  13. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    24
    Rep Power
    0
    Originally Posted by Jacques1
    Hi,

    the solution is to use a library and stop reinventing the wheel.

    And of course you must escape variables before you insert them into the HTML content -- just like everywhere else.
    Thanks again. I'll first tackle the escape portion. Am I on the right track as far as that with the code below?

    PHP Code:
    $date2 = new DateTime();  
     
    $date2->setTimezone(new DateTimeZone('America/New_York'));
                  
    $fdate2 html_escape($date2->format('m/d/Y h:i:s A'));

    $lot html_escape($_POST['lot']);
     
    $block html_escape($_POST['block']);
     
    $notes html_escape($_POST['notes']);

    $smt $db->prepare('SELECT Builder, Community FROM BuilderCommunity   WHERE BuilderCommunityID =  :buildercommunityid ');
     
    $smt->execute(array(  ':buildercommunityid' => $_POST['BuilderCommunity']));
     
    $smt->bindColumn('Builder'$builder);
     
    $smt->bindColumn('Community'$community);
     
    $smt->fetch(PDO::FETCH_BOUND);
     
     
    $builder1 html_escape($builder);
     
    $community1 html_escape($community);
     
     
    $smt $db->prepare('SELECT jobtypedescription FROM JobType   WHERE jobtypeid =  :type ');
     
    $smt->execute(array( ':type' =>$_POST['type']));
     
    $smt->bindColumn('jobtypedescription'$typedescription);
     
    $smt->fetch(PDO::FETCH_BOUND);
     
     
    $typedescription1 html_escape($typedescription)

    $to html_escape($email);
    $subject html_escape("Email Notification");
    $from html_escape("aaa@abc.com");
    $body = <<<EOD
    <br><br>
    Builder: 
    $builder1 <br>
    Community: 
    $community1 <br>
    Lot:  
    $lot  <br>
    Block: 
    $block <br>
    Type: 
    $typedescription1 <br>
    Notes: 
    $notes <br>
    Date: 
    $fdate2 <br>
    EOD;
    $headers html_escape("From:" $from "\r\n");
    $headers .= html_escape("Content-type: text/html\r\n");
    mail($to,$subject,$body,$headers); 
  14. #8
  15. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,957
    Rep Power
    1046
    Not quite. The html_escape() function escapes strings for HTML (hence the name). You cannot use it for anything else. You can't simply run all input through the function and expect it to magically make everything secure.

    Escape the variables you insert into the HTML message. And then let PHPMailer take care of the rest.
    The 6 worst sins of security ē How to (properly) access a MySQL database with PHP

    Why canít I use certain words like "drop" as part of my Security Question answers?
    There are certain words used by hackers to try to gain access to systems and manipulate data; therefore, the following words are restricted: "select," "delete," "update," "insert," "drop" and "null".
  16. #9
  17. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    24
    Rep Power
    0
    Oh ok. So I'll just limit the escape to what is in the body portion:

    PHP Code:
    $body = <<<EOD 
    <br><br
    Builder$builder1 <br
    Community$community1 <br
    Lot:  $lot  <br
    Block$block <br
    Type$typedescription1 <br
    Notes$notes <br
    Date$fdate2 <br
    EOD
    Actual escaping:

    PHP Code:
    $date2 = new DateTime();  // This date and time variable will be used to display it to the end user as 3:50 PM but it will be saved in the table as a 24 hour format in $fdate
                  
    $date2->setTimezone(new DateTimeZone('America/New_York'));
                  
    $fdate2 html_escape($date2->format('m/d/Y h:i:s A'));

    $lot html_escape($_POST['lot']);
     
    $block html_escape($_POST['block']);
     
    $notes html_escape($_POST['notes']);
     
     
    $smt $db->prepare('SELECT Builder, Community FROM BuilderCommunity   WHERE BuilderCommunityID =  :buildercommunityid ');
     
    $smt->execute(array(  ':buildercommunityid' => $_POST['BuilderCommunity']));
     
    $smt->bindColumn('Builder'$builder);
     
    $smt->bindColumn('Community'$community);
     
    $smt->fetch(PDO::FETCH_BOUND);
     
     
    $builder1 html_escape($builder);
     
    $community1 html_escape($community);
     
     
    $smt $db->prepare('SELECT jobtypedescription FROM JobType   WHERE jobtypeid =  :type ');
     
    $smt->execute(array( ':type' =>$_POST['type']));
     
    $smt->bindColumn('jobtypedescription'$typedescription);
     
    $smt->fetch(PDO::FETCH_BOUND);
     
    $typedescription1 html_escape($typedescription
  18. #10
  19. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    24
    Rep Power
    0
    Originally Posted by Jacques1
    Hi,

    the solution is to use a library and stop reinventing the wheel.

    And of course you must escape variables before you insert them into the HTML content -- just like everywhere else.
    Wow Jacques. PHPMailer was so easy. I just uploaded the class.phpmailer.php file to my web server and just called the class file and added my variables to the various functions.

    Thanks again!

IMN logo majestic logo spyfu logo threadwatch logo seochat tools logo