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

    Join Date
    Aug 2013
    Location
    China
    Posts
    21
    Rep Power
    0

    PHPMailer - Securing login details


    As the title suggests I'm wondering what the best way to safely secure my email login details. At the moment it's stored as plain text in the mail.php file, shown below (all working correctly).

    PHP Code:
    <?php // SEND MAIL
    require_once '../lib/phpmailer/class.phpmailer.php';

    $mail = new PHPMailer();
    $mail->IsSMTP();
    $mail->CharSet="UTF-8";
    $mail->SMTPSecure 'tls';
    $mail->Host 'smtp.gmail.com';
    $mail->Port 587;
    $mail->Username 'XXX@gmail.com';
    $mail->Password '#####';
    $mail->SMTPAuth true;

    $mail->From 'XXX@gmail.com';
    $mail->FromName 'XXX';
    $mail->addAddress('YYY@gmail.com''YYY');
    $mail->addReplyTo('XXX@gmail.com''XXX');

    $mail->isHTML(true); 
    $mail->Subject 'Test email';
    $mail->Body    'This is the HTML message body <b>in bold!</b>';
    $mail->AltBody 'To view this message, please use an HTML compatible email client.';

    if(!
    $mail->send()) {
       echo 
    'Message could not be sent.';
       echo 
    'Mailer Error: ' $mail->ErrorInfo;
       exit;
    }
    echo 
    'Message has been sent';
    ?>
    Options I've found are: storing the uname and password in an *.ini file and loading it at the top of this file, or defining it in php somewhere then loading the definition?

    Also, if this email is being sent from the server (for email confirmation and password reset) do I need to run a REGEX query on the body?

    Thanks in advance,

    -Ifor
  2. #2
  3. --
    Devshed Expert (3500 - 3999 posts)

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

    the first thing you should definitely stop doing is output internal error messages on your website. That's the perfect way to leak the credentials. I hope that no error message will ever contain the password, but they may very well reveal the username and other critical data.

    Write the error messages into a log, never into the output.

    Apart from that, the question is: What do you want to achieve? What's the concrete goal with regard to security?

    Currently, the password is only readable by the webserver and the PHP process (assuming the permissions are correct). And a website visitor can't access it directly. With your current setup, there's not much more you can do. The only (theoretical) improvement I could think of would be to protect the password against a misconfigured webserver which suddenly starts to send PHP scripts as plaintext. If that's what you want, you'd put the password into a file outside of the document root and read it from the script.

    If you want a real improvement, you have to completely separate the email logic from your application: Whenever an email should be sent, you only store the data in the database. The actual work is done by a cronjob which regularly checks the database and sends the emails.

    This has several benefits:

    • The credentials are isolated from the application. Attacks against your application will not directly put the credentials at risk.
    • You can send the emails in a controlled manner. With your current setup, you probably send out a mail whenever the user asks you to. This is begging for a DoS attack: An attacker could simply make your appliction send a lot of emails in a short amount of time until the email account becomes unresponsive -- or maybe Google even blocks your account due to abuse. If you have lots of traffic on your website, this situation may even occur naturally.
    • This model is much more robust. If there's an error or an issue with the webserver, the emails won't be lost. They can simply be sent later.
    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".
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2013
    Location
    China
    Posts
    21
    Rep Power
    0
    Originally Posted by Jacques1
    Hi,

    the first thing you should definitely stop doing is output internal error messages on your website. That's the perfect way to leak the credentials. I hope that no error message will ever contain the password, but they may very well reveal the username and other critical data.

    Write the error messages into a log, never into the output.
    Thanks, yeah it's on the to do list. I've been reading your articles on security, very useful.

    Originally Posted by Jacques1
    If you want a real improvement, you have to completely separate the email logic from your application: Whenever an email should be sent, you only store the data in the database. The actual work is done by a cronjob which regularly checks the database and sends the emails.

    This has several benefits:

    • The credentials are isolated from the application. Attacks against your application will not directly put the credentials at risk.
    • You can send the emails in a controlled manner. With your current setup, you probably send out a mail whenever the user asks you to. This is begging for a DoS attack: An attacker could simply make your appliction send a lot of emails in a short amount of time until the email account becomes unresponsive -- or maybe Google even blocks your account due to abuse. If you have lots of traffic on your website, this situation may even occur naturally.
    • This model is much more robust. If there's an error or an issue with the webserver, the emails won't be lost. They can simply be sent later.
    Could you elaborate further? Do you mean I create another table, like this maybe?

    Code:
    mailto,body,time_requested,is_sent
    If not, please clarify, thanks again for the help.

    -Ifor
  6. #4
  7. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,957
    Rep Power
    1046
    Originally Posted by iforwms
    Could you elaborate further? Do you mean I create another table, like this maybe?

    Code:
    mailto,body,time_requested,is_sent
    Yes, something like that.

    However, I wouldn't store the complete email, because this is a waste of space, it makes it (almost) impossible to analyze the email-related data, and it leads to problems as soon as the email is supposed to contain up-to-date information (like the time when it was sent).

    Instead, I'd only store the necessary data and do the actual rendering in the cronscript.
    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".
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2013
    Location
    China
    Posts
    21
    Rep Power
    0
    Originally Posted by Jacques1
    Yes, something like that.

    However, I wouldn't store the complete email, because this is a waste of space, it makes it (almost) impossible to analyze the email-related data, and it leads to problems as soon as the email is supposed to contain up-to-date information (like the time when it was sent).

    Instead, I'd only store the necessary data and do the actual rendering in the cronscript.
    So basically you're saying the login details are safe, provided the permission settings are correctly configured, but the only problem is the chance of a DoS attack, correct?

    If so, I think I'm going to record the timestamp of when they requested the password reset, then limit requests to 1 a day, with the account being blocked after too many requests. Do you think this would this be a satisfactory approach?

    -Ifor
  10. #6
  11. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,957
    Rep Power
    1046
    Originally Posted by iforwms
    So basically you're saying the login details are safe, provided the permission settings are correctly configured, but the only problem is the chance of a DoS attack, correct?
    If you stick to the current model of sending the emails directly from the application, the credentials are not safe. Since the application has full access to them, they could be exposed through a security vulnerability.



    Originally Posted by iforwms
    If so, I think I'm going to record the timestamp of when they requested the password reset, then limit requests to 1 a day, with the account being blocked after too many requests. Do you think this would this be a satisfactory approach?
    No, because an attacker could simply have many accounts send a single request instead of having one account send many requests. They could also create tons of registrations in a short amount of time and get you to send out all the confirmations emails. Do you want to limit the total number of registrations per day?

    Those limits would also affect legitimate users: They won't be able to reset their password if the first attempt failed or if somebody has already used their email address -- which adds another DoS vulnerability.

    The problem cannot be solved by limiting the incoming email requests. You have to solve it by processing them in a controlled manner.
    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".

IMN logo majestic logo threadwatch logo seochat tools logo