This post covers the Email Injection section of the PHP Security chapter when studying for the Zend PHP 7 Certification.
PHP contains functions and classes that assist with sending mail, and as a result, some security measures should be taken to prevent injection of spam-related content into the email.
When sending an email using the standard mail()
function, you may have code that looks similar to the below.
mail("customer@example.com", "Contact Form Reply", $message, "From: $email" );
The code above sends the message to customer@example.com
in response to their contact form submission to the email address stored in the $email
variable, which is typically obtained from the web form.
If the script takes no effort to validate the $email
variable before calling mail()
, it is possible for a spammer to inject additional lines into the $email
variable like so:
some-email-address@example.com
CC: another-email-address@example.com, yet-another-email-addresses@example.com, etc-etc@example.com
The PHP mail()
function will insert those lines and deliver the mail to everyone on that list. This is a simple example of email injection.
So to filter valid emails for use in the recipient email field, you can use the filter_var()
function.
<?php
$email = filter_var($_POST['recipient_email'], FILTER_VALIDATE_EMAIL);
if ($email === FALSE) {
echo 'Invalid email';
exit(1);
}
The filter_var()
function filters a variable with a specified filter. The two parameters used in this function include the variable to check against, and the in-built filter to be used.
Some of the filters that can be used include:
This will make sure your users only supply singular, valid emails, which you can then pass to the mail()
function.
When the mail()
function talks directly to an SMTP server, starting lines with full stops will need to be prevented in the message body. Therefore a simple str_replace()
function should be used.
$body = str_replace("\n.", "\n..", $body);
It is also possible to inject via the subject, as well, but since there is no FILTER_VALIDATE_EMAIL_SUBJECT
filter available when using filter_var()
, the filtering will need to be performed yourself.
$subject = str_ireplace(array("\r", "\n", '%0A', '%0D'), '', $_POST['subject']);
Other techniques of preventing email injection include:
View the other sections:
Note: This article is based on PHP version 7.0.