Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

Possible Duplicate:
PHP mail() Header Injection Prevention

Since I only started learning about header injection in the PHP mail() function, am uncertain if the form/code below is vulnerable to attack and I am asking for advice.

I have been slowly building this over a long period of time, and would not be a very "Happy Camper" if subjected to attacks.

Integrated PHP and submission form

<?php

$target_site = 'http://www.somewhere.xxx/some_folder/try_to_access.php';

if (isset($_SERVER['HTTP_REFERER']) && preg_match("/".preg_quote($target_site,"/")."/i",$_SERVER['HTTP_REFERER'])) {


$file = "good_emails.txt";

$lines = count(file($file));


if ($lines > 100) {


header("Location: not_available_to_submit.php");

}

else {


if(isset($_POST['submit'])) {

if(trim($_POST['email']) == '')  {
$hasError = true;
} else if (!eregi("^[A-Z0-9._%-]+@[A-Z0-9._%-]+\.[A-Z]{2,4}$",   trim($_POST['email']))) {
$hasError = true;

echo "<font color=\"#CC3300\"><b>ERROR! Please enter a valid E-mail address.</b></font>";

} 

else {


if(trim($_POST['accept_terms']) == '') {
$hasError = true;

echo "<font color=\"#CC3300\"><b>ERROR! Please accept the terms and conditions.</b></font>";


} else {

$accept_terms = trim($_POST['accept_terms']);

}

$email = trim($_POST['email']);


}


if(!isset($hasError)) {

include 'form_validater.php';

}
}

}


}

else {


header("Location: improper_referer.php");

}


?>


<!DOCTYPE html>
<head>

</head>

<body>

<h2>Enter your E-mail address.</h2>

<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">

<input type="checkbox" name="accept_terms" value="accepted-terms" id="accept_terms" />
<i>Check the box if you accept the terms and conditions.</i>

<br><br>

<input type="text" size="35" name="email"> 
<input id="button" type="submit" name="submit" value="Submit" />

</form>
<br>
<b><u>Privacy policy:</u></b>
<br>
Email remains safe and not resold. You will receive an E-mail shortly after your submission, in order to <b>confirm.</b>

</body>
</html>

And my form validating script - form_validater.php

<?php

$emails = file_get_contents("good_emails.txt");

$email = $_POST['email'];

if ( preg_match( "/(?:^|\W){$email}(?:\W|$)/", $emails ) ) {


header('Location: exists_sorry.php');

}

else {

header('Location: thank_you.php');

$server_address = $_SERVER['SERVER_ADDR'];
$port_used = $_SERVER['SERVER_PORT'];
$ip_address = $_SERVER['REMOTE_ADDR'];


$today = mktime(0, 0, 0, date("m"), date("d"), date("y"));

$today2 = date('Y-m-d H:i:s', time() );


$currenttime = date('h:i:s:u');
list($hrs,$mins,$secs,$msecs) = split(':',$currenttime);


$email = $_POST['email'];

$to = "me@somewhere.com";
$subject = "New Email Address sent";
$headers = "From: $email\n";

$message = "A visitor to your site has sent the following email address to be added.\n
Email Address: $email

Used on Date: $today2

IP Address: $ip_address
Server address: $server_address
Port used: $port_used";

$user = "$email";

$usersubject = "Please confirm your email.";

$userheaders = "From: ".$_POST['email'];

$hash = hash('sha256', "mysalt".$email."addingmoresalt");


$usermessage = "Please click the link below to confirm your E-mail address: \n\nhttp://www.somewhere.xxx/confirm.php?email=".urlencode($email)."&hasher=$hash
\n
If you feel that you did not authorize this, simply ignore this message.";

mail($to,$subject,$message,$headers);

mail($user,$usersubject,$usermessage,$userheaders);

$f = fopen('tmp_emails.txt', 'a+');

fwrite($f, $email." ");

fwrite($f, "Used on ".date("m/d/Y", $today). (" $hrs:$mins:$secs")." ");

fwrite($f, "IP address: ".$ip_address."\n");

fclose($f);


}

?>
share|improve this question

migrated from stackoverflow.com Jul 12 '12 at 13:17

This question came from our site for professional and enthusiast programmers.

marked as duplicate by Rory Alsop Jul 13 '12 at 9:16

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

1  
Yes its unsafe, $userheaders = "From: ".$_POST['email']; and eregi is DEPRECATED you should use filter_var($_POST['email'], FILTER_VALIDATE_EMAIL) –  Lawrence Cherone Jun 14 '12 at 21:56
2  
There are a number of PHP classes that provide injection protection for you. I'd strongly suggest using one of those. A few are listed at the bottom of this page. –  jedwards Jun 14 '12 at 21:57
1  
Skip using mail() and switch to PHPMailer or Swiftmailer, and your worries will be over. –  Marc B Jun 14 '12 at 21:59
    
@MarcB I searched for PHPMailer and found multiple versions of it. Do you have a specific link by chance? –  Fred Jun 14 '12 at 22:11
2  
php.net/manual/en/filter.examples.validation.php –  Lawrence Cherone Jun 15 '12 at 2:37

1 Answer 1

The mail() function uses an additional_headers parameter, which could be used to set other headers. You just have to separate them by a newline character.

Here is what you have to check: Let's say, that you have got an input which allows you to type To: e-mail. You type there eg. mymail@stackexchange.com and the e-mail is sent to that address. Try to inject another header, let's say Bcc::

  • mymail@stackexchange.com%0aBcc:anothermail@stackexchange.com

  • mymail@stackexchange.com%0d%0aBcc:anothermail@stackexchange.com

You shoudn't forget to check if you code isn't vulnerable to SMTP Injection. Let's say that your script generate SMTP commands:

MAIL FROM: first_email@stackexchange.com
RCPT TO: second_email@stackexchange.com
DATA
From: first_email@stackexchange.com
To: second_email@stackexchange.com
Subject: Important e-mail
text

.

This commands could be generated by request: ?from=first_email@stackexchange.com&Subject=Important+e-mail&message=text.

However you could try to inject another commands into Subject parameter as follows: ?from=first_email@stackexchange.com&Subject=Important+e-mail%0d%0a%2e%0d%0aMAIL+FROM:+attacker@stackexchange.com%0d%0aRCPT+TO:+victim@stackexchange.com%0d%0aDATA%0d%0aFrom:+attacker@stackexchange.com%0d%0aTo:+victim@stackexchange.com%0d%0aSubject:+Bum%0d%0ainjected%0d%0a%2e%0d%0a&message=text If your webapp is vulnerable, then it'll generate two different e-mail messages:

MAIL FROM: first_email@stackexchange.com
RCPT TO: second_email@stackexchange.com
DATA
From: first_email@stackexchange.com
To: second_email@stackexchange.com
Subject: Important e-mail
text

.
MAIL FROM: attacker@stackexchange.com
RCPT TO: victim@stackexchange.com
DATA
From: attacker@stackexchange.com
To: victim@stackexchange.com
Subject: Bum
injected

.

share|improve this answer
    
How Subject=Important%0d%0a%2e%0d%0a turns into Subject: Important e-mail text .? –  curiousguy Jul 12 '12 at 21:20
    
Thanks. It's corrected now. It should have been: subject=Important+email and message=text. –  p____h Jul 13 '12 at 14:26

Not the answer you're looking for? Browse other questions tagged or ask your own question.