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:
<?php
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.
12.1.2. Set variables_order
The
default PHP
configuration automatically creates global variables from the
environment, cookies,
server information, and GET and
POST parameters. The
variables_order
directive in
php.ini controls the order and presence of these
variables. The default value is "EGPCS", meaning
that first the environment is turned into global variables, then GET
parameters, then POST parameters, then cookies, then server
information.
Allowing GET requests, POST requests, and cookies from the browser to
create arbitrary global variables in your program is dangerous. A
reasonable security precaution is to set
variables_order to "ES":
variables_order = "ES"
You can access form parameters and cookie values via the
$_REQUEST, $_GET,
$_POST, and $_COOKIE arrays, as
we discussed in Chapter 7.
For maximum safety, you can disable
register_globals in your
php.ini file to prevent any global variables
from being created. However, changing
register_globals or
variables_order will break scripts that were
written with the expectation that form parameters would be accessible
as global variables. To fix this problem, add a section at the start
of your code to copy the parameters into regular global
variables:
$name = $_REQUEST['name'];
$age = $_REQUEST['age'];
// ... and so on for all incoming form parameters