How to secure a form which sends out emails

php, phpmailer, recaptcha

Solution

For those who doesn't know what header injection (called by OP email injection) is: Even if we assume captcha is uncrackable, a human can fill your form, add some spam comment, and insert a BCC header with thousands of e-mail addresses and your script will send them.

So you should not allow any newlines in any of the headers (to, subject)

PHPMailer takes care of this, here is the relevant part of the code:

$name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
if (!$this->ValidateAddress($address)) {
   $this->SetError($this->Lang('invalid_address').': '. $address);

Recaptcha is breakable, and some spam can be send. You are effectively limiting the spam, but if it's important not to allow any spam, then you need a spam filter on the content of the e-mail, as you can never guarantee that the form will not be send by a human, who wants to send some spam messages. Or you can add a limit of messages send from a given IP per hour so you will effectively limit the amount of spam messages that can be send, even if the captcha is cracked or a human is filling it. And you may add a check so the same message content can't not be send to more than X addresses. This is if it's a popular server and it's really important to protect it from sending spam messages; for general use your code is good enough.

Problem

I have the following code which sends emails out. Is this good/secure enough for a production environment. i.e. will it stop bots, curl scripts sending spam using it, and stop email injections etc etc? ``` <?php require_once('recaptchalib.php'); $privatekey = "private keys goes here"; $resp = recaptcha_check_answer ($privatekey, $_SERVER["REMOTE_ADDR"], $_POST["recaptcha_challenge_field"], $_POST["recaptcha_response_field"]); if (!$resp->is_valid) { // What happens when the CAPTCHA was entered incorrectly die ("The reCAPTCHA wasn't entered correctly. Go back and try it again. " . "(reCAPTCHA said: " . $resp->error . ")"); } else { require 'class.phpmailer.php'; //Create a new PHPMailer instance $mail = new PHPMailer(); //Set who the message is to be sent from $mail->SetFrom('oshirowanen@localhost.com'); //Set who the message is to be sent to $mail->AddAddress($_POST['email']); //Set the subject line $mail->Subject = 'subject goes here'; //Replace the plain text body with one created manually $mail->Body = $_POST['message']; //Send the message, check for errors if(!$mail->Send()) { die ("Mailer Error: " . $mail->ErrorInfo); } else { echo "Message sent!"; } } ?> ``` So basically, what I am asking is, is the above code safe enough, secure enough, good enough for a production environment?

Original source

Related problems