Building a Secure Contact Form with PHP and mail()

A contact form is a classic first PHP project, and doing it securely takes only slightly more code than doing it naively — worth the extra few lines.

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $name = trim(strip_tags($_POST['name'] ?? ''));
    $email = filter_var($_POST['email'] ?? '', FILTER_VALIDATE_EMAIL);
    $message = trim(strip_tags($_POST['message'] ?? ''));

    if (!$email || strlen($name) < 2 || strlen($message) < 10) {
        $error = "Please fill out all fields correctly.";
    } else {
        $headers = "From: noreply@example.com\r\n";
        $headers .= "Reply-To: " . $email . "\r\n"; // never inject raw user input into headers
        $safeMessage = "Name: $name\nMessage: $message";

        mail('you@example.com', 'Contact form submission', $safeMessage, $headers);
        $success = "Thanks, we'll be in touch.";
    }
}

Header Injection: The Classic Contact Form Bug

Never put raw user input directly into an email header without stripping newlines — an attacker can inject \r\nBcc: spamlist@evil.com into a name field and turn your contact form into a spam relay. Stick to filter_var for the email field specifically, and never allow user input in the “To” header at all.