Search code examples
phpformscode-injection

PHP Contact Form Best Practice: Input Validation not working


My form input validation is not working as I expect it to work.

<?php
$name = $_POST['name'];
$email = $_POST['email'];
$message = $_POST['message'];
$from = 'From: Kontaktformular'; 
$to = 'meine@mail.de'; 
$subject = 'Kontaktformular';

$body = "From: $name\n E-Mail: $email\n Message:\n $message";

In this Part I try to validate the input:

$email = filter_var($_POST['email'], FILTER_VALIDATE_EMAIL);

if ($email === FALSE) {
    echo 'Invalid email';
    exit(1);
}

$body = str_replace("\n.", "\n..", $body);

Now I try to send the mail if the input is not NULL:

if(isset($_POST['Submit'])) {
    if (mail ($to, $subject, $body, $from)) {
    echo '<p>Message was sent!</p>';
    } else {
    echo '<p>Something went wrong :( Please try again</p>';
    }
} else {
    die ("Direct access not allowed!");
}
?>

My Problem is, that my the code returns either "Invalid email" or "Direct access not allowed!", but I am not sure what I am doing wrong.

My HTML form:

<form method="post" action="php-contact.php" class="animated fadeIn">
<label>Name</label>
<input name="name" placeholder="Name">

<label>E-Mail</label>
<input name="email" type="email" placeholder="E-Mail, zum antworten&hellip;">

<label>Nachricht</label>
<textarea name="message" placeholder="Nachricht&hellip;"></textarea>

<input id="submit" name="submit" type="submit" value="Absenden">
</form>

I tried to use these code examples: Proper prevention of mail injection in PHP


Solution

  • You were doing the processing in the wrong order. You need firstly to check that the various form fields are present within the POSTed data before trying to assign to variables which then get used to construct the message.

    <?php
        /* test METHOD and if fields are present in POST array */
        if( $_SERVER['REQUEST_METHOD']=='POST' && isset( $_POST['submit'], $_POST['name'], $_POST['email'], $_POST['message'] ) ){
    
            /* do some sanitation and validation on user input */
            $name=filter_input( INPUT_POST, 'name', FILTER_SANITIZE_STRING );
            $email=filter_var( filter_input( INPUT_POST, 'email', FILTER_SANITIZE_EMAIL ), FILTER_VALIDATE_EMAIL );
            $message=filter_input( INPUT_POST, 'name', FILTER_SANITIZE_STRING );
    
            /* if the sanitation and validation succeeds, continue processing */
            if( $name && $email && $message ){
    
                $from = 'From: Kontaktformular'; 
                $to = 'meine@mail.de'; 
                $subject = 'Kontaktformular';
    
                $body = "From: $name\nE-Mail: $email\nMessage:\n $message"; 
    
                $status=mail( $to, $subject, $body, $from );
                echo $status ? '<p>Message was sent!</p>' : '<p>Something went wrong :( Please try again</p>';
    
            } else {
                echo "bogus!"
            }
    
        } else {
            die("Direct access not allowed!");
        }
    ?>