1

I am trying to verify 2 things

  1. That the form used to call the script to insert a record into the database was executed by a real user pressing the submit button,opposed to bot or SQL injection threat.

  2. To verify that all fields contain data so as to prevent the entry of a row of empty data.

The statement I have now is:

if (!$_POST['submit']) {    
   die('Error: ' . mysqli_error());
   echo "Please complete all form fields!";
   echo "<meta http-equiv='Refresh' content='3; URL=../add.php'>";
}

This if statement is suppose to do both but I am not sure if this is the best way to do it and I do not see that it is checking / preventing against empty fields. The form has a submit button with the name="submit".

Any thoughts or suggestions is appreciated.

1
  • 1
    Change if (!$_POST['submit']) { to if (!isset($_POST['submit'])){ it's the simplest method. Commented Jan 4, 2014 at 0:49

6 Answers 6

2

One technique in bot detection is to use a honeypot field such as this

<input type="text" name="check" value="" style="display:none;" />

and then to detect a bot

if (!empty($_POST['check'])) { /* bot detected! */ }

The reason this works reasonably well is because bots are dumb. They will try to fill out all of the proper fields that may be relevant to a successful submission so they can avoid problems with required fields. It is important to note that type="text" was used instead of type="hidden" because most bots would know that hidden fields aren't part of required field validation.

Checking against $_POST['submit'] will often not work because many bots would emulate the web-page.

Sign up to request clarification or add additional context in comments.

4 Comments

Answers only one question of OP but this is clever.
@AyeshK Thanks! There's a lot of validation info/methods out there for OP to do this himself, and he hasn't posted adequate code other than his attempt to check $_POST['submit']. His bigger concern seemed to be for bot detection so I focused on that part.
maybe since it's too late or me dumb, but I can't get why a bot should be caught by that. Thinking about how I would write a both, I would make it so that it submit check=, i.e. an empty value, for a field it does not know how to fill to make it meaningful. But of course there are bot for different purposes, so it must depend on this too.
@ShinTakezou It's not a surefire way, but the general concept is that a crawling spambot can't be bothered to "pick and choose" the non-required fields from the required ones, so it just fills all of them out. Yes you can analyze the context of input fields to put particular data in each but the name attribute of an input field may not be contextually sensible (since it's part of the markup, not for the end-user.) All the spambot would really care about is the textarea which is typically used for the "message", "blog post", etc.
1

You have to check every field one by one to be sure that's every fields has been filled. The $_POST['submit'] entry exists if you click on the submit button actually.

if (!$_POST['name'] || empty($_POST['name'])
    || !$_POST['email'] || empty($_POST['email'])
    || ...) {    
    echo "Please complete all form fields!";
    echo "<meta http-equiv='Refresh' content='3; URL=../add.php'>";
}

A lot of methods exists to refactor and improve the writing of this kind of verification. An example, from W3Schools:

<?php
// define variables and set to empty values
$name = $email = $gender = $comment = $website = "";

if ($_SERVER["REQUEST_METHOD"] == "POST")
{
  // Sanitize every var from SQL injection, XSS and strip spaces...
  $name = test_input($_POST["name"]);
  $email = test_input($_POST["email"]);
  $website = test_input($_POST["website"]);
  $comment = test_input($_POST["comment"]);
  $gender = test_input($_POST["gender"]);

 if(empty($name) || empty($email) || empty($website) || empty($comment) || empty($gender)) {
    echo "Please complete all form fields!";
    echo "<meta http-equiv='Refresh' content='3; URL=../add.php'>";
 }
}


function test_input($data)
{
  $data = trim($data);
  $data = htmlspecialchars(addslashes($data));
  return $data;
}
?>

2 Comments

ok this makes sense for checking fields, what are your thought regarding checking the status of the submit, is this recommended for security?
If data expected are submitted, I think you don't need to check the submit button. It can be a very cheap security to avoid form validation from the outside, but this has to be managed with csrf token: en.wikipedia.org/wiki/Cross-site_request_forgery (but I don't want to bother you with this for the moment, it's maybe a level a bit too high for you for the moment :) )
0

You should do it like this:

if(isset($_POST['submit'])) {
    foreach($_POST as $val) {
        if(trim($val) == '' || empty($val)) {
            //empty field, do something
            ...
            header("Location: /add.php?error=empty_fields");
            die();
        }
    }
    //all seems to be ok
    ...
}

To prevent SQL injection, use PDO and you'll forget about it.

1 Comment

I really like this approach however I would need to make the header("Location: ../add.php?error=empty_fields"); stall or wait for 3-5 secs so I can display a message such as: echo "Please complete all form fields!"; I have been using this: echo "<meta http-equiv='Refresh' content='3; URL=../add.php'>"; as it allows me to make a delay, is this a bad approach compared to the header() usage?
0
  1. You can't be sure it's not a bot. And you can avoid SQL injection with good easy coding practices, but your code fragment is too small to show any of these, if you are using them or not.
  2. Add the check client-side too (using Javascript); if you receive empty values, then likely the form was submitted in some other way than a common browser — but there could be other reasons, e.g. Javascript disabled, so you can't be sure.

You can check for the User-Agent too, but remember that they can be faked. And that bot can add a correct Submit field as well!

Comments

0

Step 1: Client Side Validation

You will need to do a little more than this to ensure fields are not empty. I would suggest starting with client-side validation using JavaScript. There area number of scripts and tutorials out there for this, I would recommend either of these two:

This will help ensure that if a user submits the form that they will be forced to fill in all form fields before the data will be sent to the server.

Step 2: Server Side Validation

If you are trying to accomplish a blanket check of form values within a form I'd do something like this:

 $form_fields = array('email','fname','lname');
 $isValid = true;
 foreach($_POST as $key=>$value){
      if(in_array($key,$form_fields)){
           if(empty($value) { 
                $isValid = false;
           }
      }
 }
 if(!isValid) {
      header("Location: /add.php?error=1");
      die();
 }

With this approach you're defining all of the field names you care about at the top of the script and just running through the $_POST object to see if there is data/value assigned. This does not, of course, take into account any validation on the type of data coming in through and I would recommend considering doing this so that you're not getting bad data. If you need to check for improperly formatted data then you will have to check each form input individually.

Step 3: Prepared SQL Statements

The last recommendation to protect against SQL injections would be to use prepared SQL statements when inserting data into the database. Or to consider an ORM that does this for you. For this I would recommend:

Optional Step: PHP Nonce

If you're worried that someone will submit SPAM through the page that processes your form, one thing you can do is implement a nonce. This cryptographic key will ensure that a form can only be submitted once, and any other submissions will be rejected. Again, I'm not sure how secure you want to be with your project but this is also something to consider.

This is a pretty good library for nonces in PHP:

Comments

0

This is the full script, sorry I did not post in the original post:

<?php
//Form fields passed to variables
$manu = mysql_real_escape_string($_POST['inputManu']);
$model = mysql_real_escape_string($_POST['inputModel']);
$desc = mysql_real_escape_string($_POST['inputDesc']);

//Connect to database using $conn
include ('connection.php');

$sql = "INSERT INTO gear (`id`,`manu`,`model`,`desc`)
    VALUES (NULL,'$manu','$model','$desc')";

//Check for empty fields
if (!$_POST['submit']) 
{   
   die('Error: ' . mysqli_error());
   echo "Please complete all form fields!";
   echo "<meta http-equiv='Refresh' content='3; URL=../add.php'>";
}
//Insert record into table 
elseif (!mysqli_query($conn,$sql))
{
die('Error: ' . mysqli_error($conn));
}
else 
{
//echo "1 record added";
echo "Success, You added the ".$manu." ".$model."";
echo "<meta http-equiv='Refresh' content='3; URL=../index.php'>";
}           
mysqli_close($conn);
?>

1 Comment

Clearly this adds empty records and I intend to test the options suggested here now assuming you still recommend the same approaches after seeing the full code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.