How to sanitze user input in PHP before mailing?

Viewed 35274

I have a simple PHP mailer script that takes values from a form submitted via POST and mails them to me:

<?php
$to = "me@example.com";

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

$body  =  "Person $name submitted a message: $message";
$subject = "A message has been submitted";

$headers = 'From: ' . $email;

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

header("Location: http://example.com/thanks");
?>

How can I sanitize the input?

5 Answers

Sanitize the post variable with filter_var().

Example here. Like:

echo filter_var($_POST['email'], FILTER_SANITIZE_EMAIL);   

Since you're not building an SQL query or anything here, the only relevant validation that I can see for those inputs is an email validation for $_POST["email"], and maybe an alphanumeric filter on the other fields if you really want to limit the scope of what the message can contain.

To filter the email address, simply use filter_var:

$email = filter_var($email, FILTER_SANITIZE_EMAIL);

As per Frank Farmer's suggestion, you can also filter out newlines in the email subject:

$subject = str_replace(array("\r","\n"),array(" "," "),$subject);

As others have noted, filter_var is great. If it's not available, add this to your toolchest.

The $headers variable is particularly bad security-wise. It can be appended to and cause spoofed headers to be added. This post called Email Injection discusses it pretty well.

filter_var is great, but another way to assure that something is an email address and not something bad is to use an isMail() function. Here's one:

function isEmail($email) {
    return preg_match('|^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]{2,})+$|i', $email);
};

So to use this, you could do:

if (isset($_POST['email']) && isEmail($_POST['email'])) {
    $email = $_POST['email'] ;
} else {
    // you could halt execution here, set $email to a default email address
    // display an error, redirect, or some combination here,
}

In terms of manual validation, limiting the length using substr(), running strip_tags() and otherwise limiting what can be put in.

Related