O'Reilly logo

Essential PHP Security by Chris Shiflett

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

Chapter 1. Introduction

PHP has grown from a set of tools for personal home page development to the world's most popular web programming language, and it now powers many of the Web's most frequented destinations. Along with such a transition comes new concerns, such as performance, maintainability, scalability, reliability, and (most importantly) security .

Unlike language features such as conditional expressions and looping constructs, security is abstract. In fact, security is not a characteristic of a language as much as it is a characteristic of a developer. No language can prevent insecure code, although there are language features that can aid or hinder a security-conscious developer.

This book focuses on PHP and shows you how to write secure code by leveraging PHP's unique features. The concepts in this book, however, are applicable to any web development platform.

Web application security is a young and evolving discipline. This book teaches best practices that are theoretically sound, so that you can sleep at night instead of worrying about the new attacks and techniques that are constantly being developed by those with malicious intentions. However, it is wise to keep yourself informed of new advances in the field, and there are a few resources that can help:

http://phpsecurity.org/

This book's companion web site

http://phpsec.org/

The PHP Security Consortium

http://shiflett.org/

My personal web site and blog

This chapter provides the foundation for the rest of the book. It focuses on teaching you the principles and practices that are prerequisities for the lessons that follow.

PHP Features

PHP has many unique features that make it very well-suited for web development. Common tasks that are cumbersome in other languages are a cinch in PHP, and this has both advantages and disadvantages. One feature in particular has attracted more attention than any other, and that feature is register_globals.

Register Globals

If you remember writing CGI applications in C in your early days of web application development, you know how tedious form processing can be. With PHP's register_globals directive enabled, the complexity of parsing raw form data is taken care of for you, and global variables are created from numerous remote sources. This makes writing PHP applications very easy and convenient, but it also poses a security risk.

In truth, register_globals is unfairly maligned. Alone, it does not create a security vulnerability—a developer must make a mistake. However, two primary reasons you should develop and deploy applications with register_globals disabled are that it:

  • Can increase the magnitude of a security vulnerability

  • Hides the origin of data, conflicting with a developer's responsibility to keep track of data at all times

All examples in this book assume register_globals to be disabled. Instead, I use superglobal arrays such as $_GET and $_POST. Using these arrays is nearly as convenient as relying on register_globals, and the slight lack of convenience is well worth the increase in security.

Tip

If you must develop an application that might be deployed in an environment in which register_globals is enabled, it is very important that you initialize all variables and set error_reporting to E_ALL (or E_ALL | E_STRICT) to alert yourself to the use of uninitialized variables. Any use of an uninitialized variable is almost certainly a security vulnerability when register_globals is enabled.

Error Reporting

Every developer makes mistakes, and PHP's error reporting features can help you identify and locate these mistakes. However, the detailed information that PHP provides can be displayed to a malicious attacker, and this is undesirable. It is important to make sure that this information is never shown to the general public. This is as simple as setting display_errors to Off. Of course, you want to be notified of errors, so you should set log_errors to On and indicate the desired location of the log with error_log.

Because the level of error reporting can cause some errors to be hidden, you should turn up PHP's default error_reporting setting to at least E_ALL (E_ALL | E_STRICT is the highest setting, offering suggestions for forward compatibility, such as deprecation notices).

All error-reporting behavior can be modified at any level, so if you are on a shared host or are otherwise unable to make changes to files such as php.ini, httpd.conf, or .htaccess, you can implement these recommendations with code similar to the following:

    <?php

    ini_set('error_reporting', E_ALL | E_STRICT);
    ini_set('display_errors', 'Off');
    ini_set('log_errors', 'On');
    ini_set('error_log', '/usr/local/apache/logs/error_log');

    ?>

Tip

http://php.net/manual/ini.php is a good resource for checking where php.ini directives can be modified.

PHP also allows you to handle your own errors with the set_error_handler() function:

    <?php

    set_error_handler('my_error_handler');

    ?>

This allows you to define your own function (my_error_handler()) to handle errors; the following is an example implementation:

    <?php

    function my_error_handler($number, $string, $file, $line, $context)
    {
      $error = "=  ==  ==  ==  ==\nPHP ERROR\n=  ==  ==  ==  ==\n";
      $error .= "Number: [$number]\n";
      $error .= "String: [$string]\n";
      $error .= "File:   [$file]\n";
      $error .= "Line:   [$line]\n";
      $error .= "Context:\n" . print_r($context, TRUE) . "\n\n";

      error_log($error, 3, '/usr/local/apache/logs/error_log');
    }

    ?>

Tip

PHP 5 allows you to pass a second argument to set_error_handler() that restricts the errors to which your custom function applies. For example, you can create a function that handles only warnings:

    <?php
    set_error_handler('my_warning_handler', E_WARNING);
    ?>

PHP 5 also provides support for exceptions . See http://php.net/exceptions for more information.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required