Thursday, February 12, 2009

Keeping safe with PHP superglobals

While I’m on the subject of security, it’s worth explaining the background to the PHP
superglobal arrays, which include $_POST and $_GET. The $_POST array contains data sent
using the post method. So it should come as no surprise that data sent by the get method
is in the $_GET array.

Before the release of PHP 4.2.0 in April 2002, you didn’t need to worry about using special
arrays to access data submitted from a form. If the name of the form element was email,
all that was necessary was to stick a dollar sign on the front, like this: $email. Bingo, you had instant access to the data. It was incredibly convenient. Unfortunately, it also left a gaping security hole. All that an attacker needed to do was view the source of your web page and pass values to your script through a query string.

When the loophole was closed, millions of PHP scripts stopped working. Inexperienced
web developers were up in arms, and harassed hosting companies changed a setting called
register_globals in php.ini to restore a little peace to their lives. You will find lots of
“advice” on the Internet to turn register_globals on in php.ini, because it will make
your life easier. This is completely misguided. Turning on register_globals is foolish for

the following reasons:
1. It’s totally insecure.
2. There is no way to override the setting for individual scripts. If your hosting company
turns register_globals off, any scripts that rely on it will break.
3. The register_globals setting has been removed completely from PHP 6. Scripts
that rely on register_globals won’t work, period.

It’s very easy to write scripts that don’t rely on register_globals, so it’s not the major
burden that some people imply. It just requires putting the name of the form element in quotes between square brackets after $_POST or $_GET, depending on the form’s method attribute.

So email becomes $_POST['email'] if sent by the post method, and $_GET['email'] if
sent by the get method. That’s all there is to it. Although the post method is more secure than get, you shouldn’t assume that it’s 100% safe. For secure transmission, you need to use encryption or the Secure SocketsLayer (SSL).

You may come across scripts that use $_REQUEST, which avoids the need to distinguish
between $_POST or $_GET. It’s less secure. Always use $_POST or $_GET instead.
Old scripts may use $HTTP_POST_VARS or $HTTP_GET_VARS, which have exactly the same
meaning as $_POST and $_GET. The longer versions have been removed from PHP 6. Use
$_POST and $_GET instead.

0 comments:

Post a Comment