0

To start of I am not an expert when it comes to PHP. I recently implemented a website email form for our website using PHP. It has three input field Name, Email and Message. They are all required field. For the Email input field, one has to enter an email address, there can only be one email address in the field and it has to have @ symbol. Then, only the script posts the fields to be sent as an email.

Following is html form:

enter image description here

Following is the HTML code for the form:

<form action="somescript.php" method="POST">
<input type="text" name="name" id="name" placeholder="Name" required>
<input type="email" name="email" id="email" placeholder="Email" required>
<textarea name="message" id="message" placeholder="Message" rows="5" required></textarea>
 <br>
<?php
require_once('recaptchalib.php');
$publickey = "LONG STRING";
echo recaptcha_get_html($publickey);
?>
<br>
<ul class="actions">
<li><input name="submit" type="submit" class="button alt" value="Send Message" /></li>
</ul>
</form>

Following is the actual script that sends out the email to us.

<?php
session_start();

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

    // check reCAPTCHA information
    require_once('recaptchalib.php');

    $privatekey = "LONG STRING";
    $resp = recaptcha_check_answer ($privatekey,
                                $_SERVER["REMOTE_ADDR"],
                                $_POST["recaptcha_challenge_field"],
                                $_POST["recaptcha_response_field"]);

    // if CAPTCHA is correctly entered!                        
    if ($resp->is_valid) { 

    $name = $_POST['name'];
    $visitor_email = $_POST['email'];
    $message = $_POST['message'];

    if (IsInjected($visitor_email)){
        $_SESSION['caperror']="Please enter a valid email address.";
        header('Location: Contact-Us.php');         
    } else {            

    $email_from = 'Website';//<== update the email address
    $email_subject = "Website email from $name";
    $email_body = "$message";

    $to = "some-dude@some-company.com";//<== update the email address
    $headers = "From: $email_from \r\n";
    $headers .= "Reply-To: $visitor_email \r\n";

    //Send the email!
    mail($to,$email_subject,$email_body,$headers);
    //done. redirect to thank-you page.
    header('Location: thank-you.html');
    }

    } else {
        // handle the CAPTCHA being entered incorrectly
        $_SESSION['caperror']="You have entered CAPTCHA incorrectly. Try again.";
        header('Location: Contact-Us.php');
    }
} else { 
    // handle the form submission error somehow
echo "error; you need to submit the form!";        
}

 // Function to validate against any email injection attempts
 function IsInjected($str)
 {
      $injections = array('(\n+)',
          '(\r+)',
          '(\t+)',
          '(%0A+)',
          '(%0D+)',
          '(%08+)',
          '(%09+)'
          );
      $inject = join('|', $injections);
      $inject = "/$inject/i";
      if(preg_match($inject,$str))
      {
           return true;
      }
      else
      {
           return false;
 }
}

?>

As far as the email field is concerned, you can only have one email address and it has to have @ symbol. However, after looking at the email I got this morning from a website visitor, I am confused as heck. The email address they enter in the form is added to the "Reply-To" header of the email address. Following is the actual Reply-To header I got for the email address which is I think IMPOSSIBLE. How did they accomplish this? I try to reproduce this error and I can't seem to do it.

enter image description here

So, how was this visitor able to do this and the question I have is what is the proper or right way of checking for email address in an email input field?

ThN
  • 3,235
  • 3
  • 57
  • 115
  • 1
    possible duplicate of [How to validate an Email in PHP?](http://stackoverflow.com/questions/5855811/how-to-validate-an-email-in-php) – oliverpool Sep 04 '15 at 13:45
  • possible duplicate of [PHP - Filter_var alternative?](http://stackoverflow.com/questions/9126226/php-filter-var-alternative) – oliverpool Sep 05 '15 at 08:41

3 Answers3

2

Alternatively you could simply use HTML5's email input type:

<input type="email" name="email">

As Mozilla Developer Network documentation states

email: A field for editing an e-mail address. The input value is validated to contain either the empty string or a single valid e-mail address before submitting. The :valid and :invalid CSS pseudo-classes are applied as appropriate.

There's also the official documentation but it can be a bit hard to read.

EDIT

Just noticed that you are actually using the email input.

If you need to validate if it's a valid email address from PHP then in my view the easiest would be to install a library does that it for you. I'd suggest using Zend Framework's validator library.

To install it run the following command from your project root:

composer require zendframework/zend-validator

Afterwards simply instantiate the validator and pass the value to it:

use Zend\Validator\EmailAddress;

$validator = new EmailAddress();
$valid = $validator->isValid($yourValue);

It will do all the work for you and you can also specify additional options if you need to as described here.

Andris
  • 5,853
  • 3
  • 28
  • 34
1

You should use PHP built-in function filter_var

<?php
$email_a = 'joe@example.com';
$email_b = 'bogus';

if (filter_var($email_a, FILTER_VALIDATE_EMAIL)) {
    echo "This ($email_a) email address is considered valid.";
}
if (filter_var($email_b, FILTER_VALIDATE_EMAIL)) {
    echo "This ($email_b) email address is considered valid.";
}
?>
oliverpool
  • 1,624
  • 13
  • 30
  • filter_var doesn't seem to want to execute... Php fails at that point. I copied your code literally, saved it and dumped into server. When I call the file, I get a blank screen. – ThN Sep 04 '15 at 15:00
  • filter_var is only supported in PHP 5.2.X or above .. my PHP is 5.1.2 – ThN Sep 04 '15 at 15:10
  • Ok, please edit your question accordingly to mention which PHP version your are using (also in the title) and say that `filter_var` is not available – oliverpool Sep 05 '15 at 08:36
  • It's then a duplicate of [PHP - Filter_var alternative?](http://stackoverflow.com/questions/9126226/php-filter-var-alternative) – oliverpool Sep 05 '15 at 08:43
1

You don't seem to actually check if the submission is a valid e-mail address, you only check for injected code via the isInjected function. So, as long as someone posts any string that doesn't have that code, your code assumes it's a true e-mail address - which is of course, not true.

Try also, using the following code before sending the e-mail:

if (! filter_var($email, FILTER_VALIDATE_EMAIL)) {
    // Handle the invalid e-mail somehow
    exit("Invalid e-mail!");
}
Amo
  • 2,884
  • 5
  • 24
  • 46