Is This Mail() Function Safe from Header Injection

Is this mail() function safe from header injection?

Header injection relies on being able to insert additional newlines into header variables, which makes the string look like a new header.

For example, allowing a subject value of Testing\nCc: spamrecipient@example.com\n\nSome body text would result in a message header containing:

Subject: Testing
Cc: spamrecipient@example.com

Some body text

i.e. the abuser has not only added additional recipients, but they've managed to supply their own body text too.

However in your case the $toaddress is constant, and even if $toaddress had been user-supplied it should be correctly sanitised by the mail() function.

Your subject header is similarly constant

The $message variable is safe because by definition that's the body text and only sent after the real headers.

That only leaves $fromaddress, and you're already using FILTER_VALIDATE_EMAIL on that which should also reject anything with a newline in it.

However you should strictly be checking the result of that test, and aborting the whole thing if the result is FALSE. As it is if the validation fails then mail() will complain about being given a blank From: address, but there's no header injection opportunity there.

As far as I can tell, then, this code is actually secure.


Also, IMHO, you shouldn't send the emails from the user-supplied email address. That would fall foul of anti-spam mechanisms such as SPF.

You should use a constant From: value belonging to your own domain. If you like you could then use a correctly sanitised value in the Reply-To header to make it easier to have the subsequent reply go to the desired address.

php mail header injection prevention

Someone would want to inject something like this:

user_address@domain.com

CC: spam_address1@domain.com, spam_address2@domain.com, spam_address3@domain.com

You do not allow \r\n which is needed for defining new header info. So your application is safe.

Are to, subject and body safe against injection using mail()?

Yes, that's true, but it's also incomplete. In the engine source code, the function php_mail_build_headers ensures headers comply with RFC 2822 § 3.6 requirements for maximum number of values. Particularly, the following headers are checked for single value:

  • orig-date
  • from
  • sender
  • reply-to
  • to
  • bcc
  • message-id
  • in-reply-to
  • subject

Yes, the message parameter is safe from header injection by definition: the message part is inserted after the separating new line between headers and body, so any header-like text inserted as part of the message will appear as literal text within the message body.

Is this php mailer file secure from injection attacks?

The term "injection" refers to code injection, with code referring to any computer language. Since every computer language is different, the problems and solutions are also different and need to be addressed in a per-language basis. However, you have a generic function that tries to prevent all kind of injections at once and, often, using the worst technique: removing user data.

For instance:

$headers = "From: " . strip_tags($from) . "\r\n";

What sense does it make to take an e-mail address and remove HTML tags from it to compose an e-mail header?

$data = htmlspecialchars($data);

You apply this to e.g. $_REQUEST['email']. Why would you want to insert HTML entities in an e-mail address?

In your code I see two potential sources for injection:

  • HTML - When you inject user data into HTML you need to ensure that user data is handled as plain text (i.e. whatever the user typed is not rendered as HTML). You can use htmlspecialchars(). You kind of do that but it's really hard to be sure.

  • E-mail headers - mail()'s fourth argument allows to define mail headers. Injecting raw user input there (which is possibly what's happening now) allows to hide the complete message body, replace it with anything else and even select new recipients. You basically have to strip new lines (again, it's hard to say whether you're doing it right...).

Sending e-mail with PHP is hard. It's better to skip good old mail() and use a third-party library like PHPMailer or Swift Mailer.

What is the best way to prevent email Injection in a mailform?

The vulnerability in mail comes from header injection. To prevent it, you can look for newlines in the header values, ie.:

"BCC: " . $email . "
X-OtherHeader: Foo-Bar

If $email contains a newline, like:

webmaster@domain.com
TO: pro@hackerz.ru

You will get an extra TO header, which is potentially malicious. Header injection allows an attacker to send an email from your mailserver to anyone, essentially turning your mailserver into a spam server.

From the looks of it your current script is safe.

Proper prevention of mail injection in PHP

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']);

Replacing deprecated eregi() with stristr(). Is this php mail script secure from header injections?

You try to blacklist headers like BCC, CC but fail to block TO, FROM.

RFC 822 on page 16 in section 4.1 it states:

This specification permits multiple occurrences of most fields. Except
as noted, their interpretation is not specified here, and their use
is discouraged.

So an attacker would be able to manipulate the message to add additional recipients and senders. You should really just be checking for newlines and carriage returns or just sanitize all the $_POST values by stripping out \r and \n characters.

<?php

function clean_string($string)
{
return str_replace(array("\n", "\r"), '', $string);
}

$to = 'myemail@gmail.com';

// the $Name is the PHP variable, the _Post['Name'] should match the name of the input boxes in the form
$Name = clean_string($Name);
$Email = clean_string($Email);
$Phone = clean_string($Phone);
$Message = clean_string($Message);

// you can format the email anyway you want.
$message = "Form submitted by $Name

Applicant Information:\n

Name: $Name

Email: $Email

Phone: $Phone

Message: $Message";

if (mail($to, 'mywebsite.com contact Form Submission', $message, "From: $Name <$Email>"))
{
echo 'Thank you ' . htmlspecialchars($Name) . ' for your interest. We will contact you shortly';
}
else
{
echo "There was a problem sending the mail. Please check that you filled in the form correctly.";
}

?>


Related Topics



Leave a reply



Submit