Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proper prevention of mail injection in PHP

Could you advise me how do I go about preventing email injection in PHP mail() without losing original message data? E.g. if I need to allow user to use \r\n, To, CC etc, so I do not want to completely strip them away from the message - I still want them delivered, but without adding any additional headers or somehow allowing mail injection to happen.

Most of the advices on internet suggest stripping that data away completely - but I do not want to do that.

I am sending plain text (non HTML) messages through PHP mail() function.

What would you advise?

like image 552
Atm Avatar asked Aug 14 '12 12:08

Atm


People also ask

How do I prevent mails sent through PHP mail () from going to spam?

Try PHP Mailer library. Or Send mail through SMTP filter it before sending it. Also Try to give all details like FROM , return-path .

Is PHP mail function secure?

This is perfectly secure; there is no way a hacker could manipulate who the E-mail gets sent to; PHP is server-side code. Thus, $email_to = "[email protected]"; cannot get manipulated from the form itself, as it is hard-coded into your PHP.

What is PHP mail () function?

PHP mail() function is used to send email in PHP. You can send text message, html message and attachment with message using PHP mail() function.


3 Answers

To filter valid emails for use in the recipient email field, take a look at filter_var():

$email = filter_var($_POST['recipient_email'], FILTER_VALIDATE_EMAIL);

if ($email === FALSE) {
    echo 'Invalid email';
    exit(1);
}

This will make sure your users only supply singular, valid emails, which you can then pass to the mail() function. As far as I know, there's no way to inject headers through the message body using the PHP mail() function, so that data shouldn't need any special processing.

Update:

According to the documentation for mail(), when it's talking directly to an SMTP server, you will need to prevent full stops in the message body:

$body = str_replace("\n.", "\n..", $body);

Update #2:

Apparently, it's also possible to inject via the subject, as well, but since there is no FILTER_VALIDATE_EMAIL_SUBJECT, you'll need to do the filtering yourself:

$subject = str_ireplace(array("\r", "\n", '%0A', '%0D'), '', $_POST['subject']);
like image 157
FtDRbwLXw6 Avatar answered Oct 18 '22 23:10

FtDRbwLXw6


Suppose you you want to put the email address of the visitor in the optional header field like so:

$headers = "From: $visitorEmailAddress";

However, if

$visitorEmailAddress

contains

"[email protected]\n\nBCC:[email protected]"

you've made yourself a spam host, opening the door for mail injection. This is a very simple example, but creative spammers and malicious hackers can sneak potentially damaging scripts in your email, since email is sent as a plaintext file. Even attachments are converted plaintext, and they can easily send attachements by adding a mimetype content line.

If your form validation for the FROM and/or TO fields is OK, you have to look at the form validation for the body of the email. I'd strip out the '-=' and '=-' characters, and prevent users from typing plain HTML by using strip_tags().

like image 43
Dirk de Man Avatar answered Oct 18 '22 23:10

Dirk de Man


Try this for a review of various options:

http://www.codeproject.com/Articles/428076/PHP-Mail-Injection-Protection-and-E-Mail-Validatio

It covers several options and tries to explain the benefits and risks of each.

like image 34
Mike Avatar answered Oct 18 '22 22:10

Mike