As the most basic precaution, you need to pay attention to your external submissions and make the first security mechanism to deal with the firewall.
Rule 1: Never trust external data or input
The first thing you must realize about web application security is that external data should not be trusted. External data includes any data that is not entered directly by the programmer in the PHP code. Any data from any other source (such as GET variables, form POST, databases, configuration files, session variables, or cookies) cannot be trusted until steps are taken to ensure security.
For example, the following data elements can be considered safe because they are set in PHP.
Copy code The code is as follows:
$myUsername = 'tmyer';
$ arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);
?>
However, the data elements below are all flawed.
Listing 2. Unsafe, flawed code
Copy the code The code is as follows:
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!
?>
Why is the first variable $myUsername defective? Because it comes directly from the form POST. Users can enter any string into this input field, including malicious commands to clean files or run previously uploaded files. You might ask, "Can't you avoid this danger by using a client-side (Javascrīpt) form validation script that only accepts the letters A-Z?" Yes, this is always a beneficial step, but as we'll see later , anyone can download any form to their machine, modify it, and resubmit whatever they need.
The solution is simple: the sanitization code must be run on $_POST['username']. If you don't do this, you risk polluting these objects any other time you use $myUsername (such as in an array or constant).
A simple way to sanitize user input is to use regular expressions to process it. In this example, only letters are expected to be accepted. It might also be a good idea to limit the string to a specific number of characters, or require all letters to be lowercase.
Listing 3. Making user input safe
Copy the code The code is as follows:
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!
function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace ("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}
?>
Rule 2: Disable PHP settings that make security difficult to implement
Now that you can’t trust user input, you should also know that you shouldn’t trust the PHP configuration on the machine. Way. For example, make sure register_globals is disabled. If register_globals is enabled, it's possible to do careless things like use a $variable to replace a GET or POST string with the same name. By disabling this setting, PHP forces you to reference the correct variables in the correct namespace. To use variables from a form POST, $_POST['variable'] should be quoted. This way you won't mistake this particular variable for a cookie, session, or GET variable.
Rule 3: If you can’t understand it, you can’t protect it
Some developers use strange syntax, or organize statements very tightly, resulting in short but ambiguous code. This approach may be efficient, but if you don't understand what the code is doing, you can't decide how to protect it.
For example, which of the following two pieces of code do you like?
Listing 4. Make the code easy to protect
Copy the code The code is as follows:
< ;?php
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:”);
//unobfuscated code
$ input = ”;
if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = ”;
}
?>
In the second cleaner snippet, it's easy to see that $input is flawed and needs to be cleaned up before it can be safely processed.
Rule 4: “Defense in depth” is the new magic weapon
This tutorial will use examples to illustrate how to protect online forms while taking the necessary measures in the PHP code that handles the form. Likewise, even if you use PHP regex to ensure that GET variables are entirely numeric, you can still take steps to ensure that SQL queries use escaped user input.
Defense in depth is not just a good idea, it ensures that you don’t get into serious trouble.
Now that the basic rules have been discussed, let’s look at the first threat: SQL injection attacks.
Prevent SQL injection attacks
In a SQL injection attack, the user adds information to a database query by manipulating a form or GET query string. For example, assume you have a simple login database. Each record in this database has a username field and a password field. Build a login form to allow users to log in.
Listing 5. Simple login form
Copy code The code is as follows: