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:
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
";
$headers .= "Reply-To: $visitor_email
";
//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('(
+)',
'(+)',
'(\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.
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?
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.";
}
?>
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!");
}
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.
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.