1

i'm worried about the security of my form. The idea is to make a form to participate in a contest in facebok. Basically just firstname, lastname, email. I've been searching through topics and there is a lot of info about security but i can't figure out what is enough security? I know that there will always be a risk that someone finds a way to abuse the security, but i'd like to find a solution, which blocks the most of them. Also if there are obvious mistakes, please let me know. Here is my code and all help and guidance is appreciated.

<?php
$dsn = 'mysql:dbname=dbname;host=localhost';
$user = '';
$password = '';

try {
    $dbh = new PDO($dsn, $user, $password);
} catch (PDOException $e) {
    echo 'Connection failed: ' . $e->getMessage();
}

$firstErr = $lastErr = $emailErr = "";
$first = $last = $email = "";

function test_input($data)
{
   $data = trim($data);
   $data = stripslashes($data);
   $data = htmlspecialchars($data);
   return $data;
}

if ($_SERVER["REQUEST_METHOD"] == "POST") {

  if (empty($_POST["first"])) {
    $firstErr = "Name is required";
    echo "<p>Firstname: $firstErr</p>";
  } else {
    $first = test_input($_POST["first"]);
    // check if name only contains letters and whitespace
    if (!preg_match("/^[a-zA-Z ]*$/",$first)) {
      $firstErr = "Only letters and white space allowed";
    echo "<p>Firstname: $firstErr</p>";
    }
  }

  if (empty($_POST["last"])) {
    $lastErr = "Name is required";
    echo "<p>Lastname: $lastErr</p>";
  } else {
    $last = test_input($_POST["last"]);
    // check if name only contains letters and whitespace
    if (!preg_match("/^[a-zA-Z ]*$/",$last)) {
      $lastErr = "Only letters and white space allowed";
        echo "<p>Lastname: $lastErr</p>";
    }
  }


  if (empty($_POST["email"])) {
    $emailErr = "Email is required";
    echo "<p>Email: $emailErr</p>";
  } else {
    $email = test_input($_POST["email"]);
    // check if e-mail address is well-formed
    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
      $emailErr = "Invalid email format";
      echo "<p>Email: $emailErr</p>";
    }
  }

    if ($firstErr == false && $lastErr == false && $emailErr == false) {
    $query = "INSERT INTO contactstable (first,last,email)  VALUES(:first,:last,:email)";
    $statement = $dbh->prepare($query);
    $statement->execute(array(
        ':first'=> $first,
        ':last'=> $last,
        ':email'=> $email
    ));
          echo "<p>Thank you for participating!</p>";
    }
    else {
        echo "Fix the missing or incorrect lines.";
    }

}

?>
Griphon
  • 29
  • 6

1 Answers1

0

You are using PDO, it already implements the security measures for 1st order injection and when the queries are parametrized the 2nd order also prevented(2nd order injection means data has been cycled through the database once before being included in a query).

But there is no harm if you implements validations for the inputs.

Sougata Bose
  • 31,517
  • 8
  • 49
  • 87
  • I was hoping to receive answers like this. That pretty much tells me, that for my purpose the form seems secure enough. I'll add some more validations. Thank you. – Griphon Nov 17 '14 at 07:47
  • 1
    [SQL injection is SQL injection, no matter where the data comes from.](http://stackoverflow.com/a/22729097/53114) – Gumbo Nov 17 '14 at 08:10