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?
Try PHP Mailer library. Or Send mail through SMTP filter it before sending it. Also Try to give all details like FROM , return-path .
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.
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.
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']);
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()
.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With