home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam  

Programming PHPProgramming PHPSearch this book

Chapter 12. Security

PHP is a flexible language that has hooks into just about every API offered on the machines on which it runs. Because it was designed to be a forms-processing language for HTML pages, PHP makes it easy to use form data sent to a script. Convenience is a double-edged sword, however. The very features that let you quickly write programs in PHP can open doors for those who would break into your systems.

It's important to understand that PHP itself is neither secure nor insecure. The security of your web applications is entirely determined by the code you write. For example, take a script that opens a file whose name was passed as a form parameter. If you don't check the filename, the user can give a URL, an absolute pathname, or even a relative path to back out of the application data directory and into a personal or system directory.

This chapter looks at several common issues that can lead to insecure scripts, such as filenames, file uploads, and the eval( ) function. Some problems are solved through code (e.g., checking filenames before opening them), while others are solved through changing PHP's configuration (e.g., to permit access only to files in a particular directory).

12.1. Global Variables and Form Data

One of the most fundamental things to consider when creating a secure system is that any information you didn't generate within the system should be regarded as tainted. You should either untaint this data before using it—that is, ensure that there's nothing malicious in it—or limit what you do with it.

In PHP, however, it's not always easy to tell whether a variable is tainted. When register_globals is enabled in the php.ini file, PHP automatically creates variables from form parameters and cookies. Poorly written programs assume that their variables have values only when the variables are explicitly assigned values in the program code. With register_globals, this assumption is false.

Consider the following code:

  if (check_privileges( )) {
    $superuser = true;
  // ...

This code assumes that $superuser can be set to true only if check_privileges( ) returns true. However, with register_globals enabled, it's actually a simple matter to call the page as page.php?superuser=1 to get superuser privileges.

There are three ways to solve this problem: initialize your variables, disable register_globals in the php.ini file, or customize the variables_order setting to prevent GET, POST, and cookie values from creating global variables.

Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.