Jump to content

Fort Knox Web Form Security Help


ceilingwalker

Recommended Posts

I’m working with my first PHP web form that submits basic information to a phpMyAdmin SQL database. I’ve been successful connecting to the database and having my form information transfer correctly, but I’m concerned my form is very insecure.

 

I’ve been reading numerous articles on “tokens”, “mysql_real_escape_string”, reCAPTCHA, etc., but I’m confused on how to implement these with my current configuration.

 

Currently I have an HTML page that post the contents of a web form via <form action="demo.php" method="post" />

 

This is the code for my web form:

 


<form action="demo.php" method="post" />
           <p>Name: <br />
<input type="text" name="name" /></p>
           <p>Phone Number: <br />
<input type="text" name="phone" /></p>
           <p>Account Number: <br />
<input type="text" name="account" /></p>
           <p>Reading: <br />
<input type="text" name="meter" /></p>

           <input type="submit" value="submit" />
           </form> 

 

I then have the form processed on my demo.php script. Here is the code for this script:

 

 




<?php

define('DB_NAME', 'example');
define('DB_USER', 'heman');
define('DB_PASSWORD', 'password1');
define('DB_HOST', 'demodatabase');

$link = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD);

if (!$link) {
die('Could not connect: ' . mysql_error());
}

$db_selected = mysql_select_db(DB_NAME, $link);

if (!$db_selected) {
die('Can\'t use ' . DB_NAME . ': ' . mysql_error());
}

$value = $_POST['name'];
$value2 = $_POST['phone'];
$value3 = $_POST['account'];
$value4 = $_POST['meter'];



$sql = "INSERT INTO demo (name, phone, account, meter) VALUES ('$value', '$value2', '$value3', '$value4')";

if (!mysql_query($sql)) {
die('Error: ' . mysql_error());
}


mysql_close();
?>

 

 

What can we do to secure my form like Fort Knox? I’m open to change the entire configuration or eliminating the HTML web form page and having the PHP process to itself if that is what is recommended.

 

Thank you for your help.

 

Link to comment
Share on other sites

Its not so much the form, its what you do with the data. Rough start...

 

1. Make SURE the data sent by the form is what you expect it to be.

 

Validate phone numbers to insure that ONLY contain numbers and  dashes, are of the proper length etc - ie 1-222-222-2222.

 

Validate names - similar to the above - you may want letters, numbers, commas, single quotes etc

 

TRAP any errors

 

Link to comment
Share on other sites

The level of "security" is wholly dependent upon the "needs" of the form. There is no need to eliminate the HTML form - even a form generated from PHP is still going to be an HTML form when it is sent to the user.

 

Here are some rough guidelines from my personal experience.

 

1. Always ensure you have full coverage on any security implemented on the back end (i.e. PHP). Any, validation you implement on the client-side (i.e. JavaScript) is great for giving the user immediate feedback and a richer user experience but it does not negate the need for the same validation server-side since JavaScript can be disabled

 

2. Always treat ALL user input as potentially malicious. Just because you have a drop-down field with three specific values does not mean a malicious user cannot actually submit a different value.

 

3. Always validate/sanitize values as appropriate for their data type. All values in a form are passed as strings, but you should validate based upon the data type that you will store them as: Strings, ints, floats, dates, etc.

 

4. As a general rule you should always trim() user input. Otherwise a value of a space would pass a required field validation.

 

5. Also, in my opinion, unless you have a specific reason not to, I would not run functions such as htmlentities(), strip_tags() etc on the input before it is stored. You can safely store the data as the user entered it and then you can use the appropriate functions when outputting the data to make it safe. A function such as strip_tags() would remove content that the user entered. That could cause problems if they are unaware of it (e.g. the username is not the same as they thought it was). And, using such as htmlentities() will increate the string length of the input causing potential problems with max length checks and database field lengths.

 

For your purposes I would think the most important things are ensuring data entered can safely be stored and to reduce the potential for bots. Bots would only be a potential issue if the form can be used by users who are not authenticated (i.e. a login system). Even then, a bots are really only used to enter data on forms - such as forums - so the data will be seen by people. I would concentrate on securing the data. Then worry about preventing bots.

 

Having said all that, I typically like to create my forms such that they post back to themselves for processing. That way, if there are errors, I can redisplay the form with the previously entered data.

 

Example script

<?php

$errorMsg = '';

//Check if form was posted
if($_SERVER['REQUEST_METHOD']=='POST')
{
    //Preprocess input
    $name    = isset($_POST['name'])    ? trim($_POST['name'])    : false;
    $phone   = isset($_POST['phone'])   ? trim($_POST['phone'])   : false;
    $account = isset($_POST['account']) ? trim($_POST['account']) : false;
    $meter   = isset($_POST['meter'])   ? trim($_POST['meter'])   : false;

    //Validate user input
    // - validations will be based on your specific needs, these are examples
    $errors = array();
    if(empty($name))
    {
        $errors[] = "Name is required";
    }

    if(empty($account))
    {
        $errors[] = "Account number is required";
    }
    elseif(!preg_match("#^\d{8}$#", $account))
    {
        $errors[] = "Account number must be an 8 digit number";
    }

    if(empty($meter))
    {
        $errors[] = "Meter number is required";
    }
    elseif(!ctype_digit($meter))
    {
        $errors[] = "Meter reading must be a number";
    }

    //Check if there were any validation errors
    if(count($errors))
    {
        $errorMsg .= "The following errors occured:<ul>\n";
        foreach($errors as $err)
        {
            $errorMsg .= "<li>{$err}</li>\n";
        }
        $errorMsg .= "</ul>\n";
    }
    else
    {
        //All validations passed, insert record

        //Ideally the DB connection data should be in a separate fiel and include()d when needed
        define('DB_NAME', 'example');
        define('DB_USER', 'heman');
        define('DB_PASSWORD', 'password1');
        define('DB_HOST', 'demodatabase');

        $link = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD);
        if (!$link) { die('Could not connect: ' . mysql_error()); }

        $db_selected = mysql_select_db(DB_NAME, $link);
        if (!$db_selected) { die('Can\'t use ' . DB_NAME . ': ' . mysql_error()); }

        //Create query, making input safe for query
        $query = srpintf("INSERT INTO demo
                              (name, phone, account, meter)
                          VALUES ('%s', '%s', '%d', '%s')",
                          mysql_real_escape_string($name),
                          mysql_real_escape_string($phone),
                          intval($account),
                          intval($meter));
        $result = mysql_query($query);

        if(!$result)
        {
            echo "There was a problem inserting the record.<br>" .  mysql_error();
            exit();
        }
        else
        {
            //Redirect to confirmation page
            //This will clear the post data so a page refresh doesn't insert another record
            header("Location: http://www.example.com/confirm.php");
            exit();
        }
    }
}

?>
<html>
<body>

<div style="color:red;"><?php echo $errorMsg; ?></div>

<form action="demo.php" method="post" />
    <p>Name: <br />
    <input type="text" name="name" value="<?php echo htmlentities($name); ?>" /></p>
    <p>Phone Number: <br />
    <input type="text" name="phone" value="<?php echo htmlentities($phone); ?>" /></p>
    <p>Account Number: <br />
    <input type="text" name="account" value="<?php echo htmlentities($account); ?>" /></p>
    <p>Reading: <br />
    <input type="text" name="meter value="<?php echo htmlentities($meter); ?>"" /></p>
    <input type="submit" value="submit" />
</form> 

</body>
</html>

Link to comment
Share on other sites

  • 1 month later...

Thank you for your help. I've managed to get everything working except for the following code. I continued to receive errors and my data wouldn't post to my SQL server:

 

//Create query, making input safe for query
        $query = srpintf("INSERT INTO demo
                              (name, phone, account, meter)
                          VALUES ('%s', '%s', '%d', '%s')",
                          mysql_real_escape_string($name),
                          mysql_real_escape_string($phone),
                          intval($account),
                          intval($meter));
        $result = mysql_query($query);

 

I switched it to the following code and it works, but I'm not sure if it is as secure as what you suggested. Any ideas of what I need to do to make this function correctly?

 

$value = $_POST['name'];
	$value2 = $_POST['phone'];
	$value3 = $_POST['account'];
	$value4 = $_POST['meter'];



$sql = "INSERT INTO DEMO  (name, phone, account, meter) VALUES ('$value', '$value2', '$value3', '$value4')";
					  
        $result = mysql_query($sql);

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.