Jump to content

mail() security question


a1ias

Recommended Posts

Hello

Having only recently begun learning PHP and mySQL (self teaching) I would consider myself to be a 'beginner' even though I have already written scripts for friends which they have found to be invaluable.

I'm a pretty quick learner and really enjoying working with PHP, I get a great deal of satisfaction from the end result of many hours of writing and troubleshooting.

It's also nice to find that a place like PHP Freaks exist, from what I've read so far it's a great community atmosphere where helping each other is not a burden for anyone.

What I'm in the process of at the moment, is going back over the scripts I've already written, and improving them from a security point of view. The advice I am here for today is with regards to the mail() feature.

I have several mail() functions in my code that requires me to assign an email address to the $to variable; something I do by simply including the email in the code of the page, e.g.

[code]
if(isset($_POST[send_email])) {

    $to = "name@emailaddress.com";

    $subject = "$_POST[subject]";

    $body = "$_POST[message]";

    $headers = "From: $_POST[email]";

    mail("$to,$subject,$body,$headers");

}[/code]

Now I can't help but worry that including the email address of the mail recipient in the code of the page is blatantly dangerous as far as attracting mail hijackers goes so I'd appreciate any kind of security advice you could give me with regard to this.

At the moment, I am calling my whole mail() script as an actual function in a require_once() file, e.g. the above would look like....

[b]main_file.php[/b]
[code]
require_once('funcs.php');

if(isset($_POST[send_email])) {

    send_the_mail();
}[/code]


[b]funcs.php[/b]
[code]
function send_the_mail() {

    $to = "name@emailaddress.com";

    $subject = "$_POST[subject]";

    $body = "$_POST[message]";

    $headers = "From: $_POST[email]";

    mail("$to,$subject,$body,$headers");

    return;
}[/code]

....but I'm guessing that this has little effect from a security point of view.

Anyway, over to the pro's, and many thanks in advance for your help.

P.S. I have the facility of a mySQL db on my host.
Link to comment
Share on other sites

Well, the main way you keep secure is that your SMTP won't accept mail from the sending address except from the ip of the server... that's what I do... no relay that way... or did I miss your question?

[!--quoteo(post=384260:date=Jun 15 2006, 12:28 PM:name=a1ias)--][div class=\'quotetop\']QUOTE(a1ias @ Jun 15 2006, 12:28 PM) [snapback]384260[/snapback][/div][div class=\'quotemain\'][!--quotec--]
Hello

Having only recently begun learning PHP and mySQL (self teaching) I would consider myself to be a 'beginner' even though I have already written scripts for friends which they have found to be invaluable.

I'm a pretty quick learner and really enjoying working with PHP, I get a great deal of satisfaction from the end result of many hours of writing and troubleshooting.

It's also nice to find that a place like PHP Freaks exist, from what I've read so far it's a great community atmosphere where helping each other is not a burden for anyone.

What I'm in the process of at the moment, is going back over the scripts I've already written, and improving them from a security point of view. The advice I am here for today is with regards to the mail() feature.

I have several mail() functions in my code that requires me to assign an email address to the $to variable; something I do by simply including the email in the code of the page, e.g.

[code]
if(isset($_POST[send_email])) {

    $to = "name@emailaddress.com";

    $subject = "$_POST[subject]";

    $body = "$_POST[message]";

    $headers = "From: $_POST[email]";

    mail("$to,$subject,$body,$headers");

}[/code]

Now I can't help but worry that including the email address of the mail recipient in the code of the page is blatantly dangerous as far as attracting mail hijackers goes so I'd appreciate any kind of security advice you could give me with regard to this.

At the moment, I am calling my whole mail() script as an actual function in a require_once() file, e.g. the above would look like....

[b]main_file.php[/b]
[code]
require_once('funcs.php');

if(isset($_POST[send_email])) {

    send_the_mail();
}[/code]
[b]funcs.php[/b]
[code]
function send_the_mail() {

    $to = "name@emailaddress.com";

    $subject = "$_POST[subject]";

    $body = "$_POST[message]";

    $headers = "From: $_POST[email]";

    mail("$to,$subject,$body,$headers");

    return;
}[/code]

....but I'm guessing that this has little effect from a security point of view.

Anyway, over to the pro's, and many thanks in advance for your help.

P.S. I have the facility of a mySQL db on my host.
[/quote]
Link to comment
Share on other sites

If you script is live and the subject line and the to address is taken from the form directly, you'll need to clean before using it in the mail function.

spammers have robots that can fill forms automatically and send mass emails from your server by injecting the headers in your mail (using the subject and the to lines).

You can go to [a href=\"http://www.securephpwiki.com/index.php/Email_Injection?seenIEPage=1\" target=\"_blank\"]http://www.securephpwiki.com/index.php/Ema...on?seenIEPage=1[/a] for more details.
Link to comment
Share on other sites

OK

The whole code for the kind of page would look like this:
[code]
<?php

if(isset($_POST[send])) {

    $to = "postmaster@server.com";

    $subject = "$_POST[subject]";

    $body = "$_POST[message]";

    $headers = "From: $_POST[email]";


    function is_valid_email($email) {

         return preg_match('#^[a-z0-9.!\#$%&\'*+-/=?^_`{|}~]+@([0-9.]+|([^\s]+\.+[a-z]{2,6}))$#si', $email);
     }

     if (!is_valid_email($email)) {

         echo 'Invalid email submitted - mail not being sent.';

         exit;
     }


    if($_SERVER['REQUEST_METHOD'] != "POST") {

        echo("Unauthorized attempt to access page.");

        exit;
    }


    function contains_bad_str($str_to_test) {

        $bad_strings = array("content-type:","mime-version:","multipart/mixed","Content-Transfer-Encoding:","bcc:","cc:","to:");

        foreach($bad_strings as $bad_string) {

            if(eregi($bad_string, strtolower($str_to_test))) {

                echo "$bad_string found. Suspected injection attempt - mail not being sent.";

                exit;
            }
        }
    }




        function contains_newlines($str_to_test) {

            if(preg_match("/(%0A|%0D|\\n+|\\r+)/i", $str_to_test) != 0) {

                echo "newline found in $str_to_test. Suspected injection attempt - mail not being sent.";

                exit;
            }
        }




    contains_bad_str($email);
    contains_bad_str($subject);
    contains_bad_str($body);

    contains_newlines($email);
    contains_newlines($subject);


    mail("$to,$subject,$body,$headers");

    echo "Thanks for your email";

    exit;
}
?>

<html>
<head>
**Head stuff in here**
</head>
<body>


<form method="POST" action="<?php echo $_SERVER['PHP_SELF']; ?>">

Your Email:<input type="text" name="email" />
Subject:</td><input type="text" name="subject" />
Message:</td><input type="text" name="message" />
<input type="submit" name="send" value="Send Email" />

</form>

</body>
</html>[/code]

And my question is basically, how safe is the email address [!--coloro:red--][span style=\"color:red\"][!--/coloro--]postmaster@server.com[!--colorc--][/span][!--/colorc--] in the above live webpage?
Link to comment
Share on other sites

[!--quoteo(post=384292:date=Jun 15 2006, 10:36 AM:name=a1ias)--][div class=\'quotetop\']QUOTE(a1ias @ Jun 15 2006, 10:36 AM) [snapback]384292[/snapback][/div][div class=\'quotemain\'][!--quotec--]And my question is basically, how safe is the email address [!--coloro:red--][span style=\"color:red\"][!--/coloro--]postmaster@server.com[!--colorc--][/span][!--/colorc--] in the above live webpage?
[/quote]
If you mean safe from being discovered, 99% (1% being of hacking/exploiting possibilities).
Safe from being spammed (bots filling the forms) though, 0% safe.
Link to comment
Share on other sites

Thankyou for that.

Thinking about increasing security against that then, I guess I could implement pulling the sender IP address and restricting that ip address from being able to send the form again within a specified time limit; or even write the ip to a session variable and restrict posting from the same ip twice in one session.
Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.