Global Variables

From SecurePHPWiki
Jump to: navigation, search

Most PHP script security holes stem from the improper use of global variables or variable polution. Global, browser-defined variables can be extremely dangerous in PHP and should be handled with caution. The first measure of security that should be taken, and is by default in all recent releases of PHP, is disabling register_globals. Enabling register_globals in php.ini potentially allows a malicious user to unexpectedly set variables through GET, POST, and cookie data. While enabling register_globals makes scripting easier, the possibly security holes that it creates are not worth the risk.

Instead, variables should be accessed explicitly using the PHP global arrays $_POST, $_GET, $_COOKIE, and $_SESSION. (See the PHP manual for in depth description and a listing of all global variable arrays.) By disabling register_globals and accessing data through the global arrays, the script is no longer at risk of unintentionally introducing an unexpected variable. Unfortunately, some users may be unable to disable register_globals. In this case, the only defense is to be sure that all variables are properly initialized. The PHP error level can be adjusted, within each script if necessary, to indicate warnings for unitialized variables as well as many other potential programming hazards.

Here is a simple example script snippet that is taken from a hypothetical page whose access is restricted to authorized users only. Programmers should always pay close attention to the design of authentication code. The following will be a brief discussion of a minimal authentication script and how to avoid various security holes common to PHP authentication procedures.

<?php if ( $authorized ) {

   // display the page content

} else {

   print( "Your access has been denied." );

} ?>

Assuming it is not initialized at an earlier point in this script, a malicious user could set $authorized to true in the URL and gain access to the page. However, had register_globals been turned off, this hole would no longer exist; with or without a properly initialized variable.

While the obvious hole in this script may have been eliminated simply by disabling register_globals, this is far from being an example of a good authentication system.

When restricting access to parts of a website by dynamically displaying links, be sure to check that the user is authorized on the linked page as well. Otherwise a malicious user may be able to guess the URL and access the page with out permission.

Cookie data that stores login information could be modified to allow a user to login as someone else. Do not trust cookie data and always verify a user is who they claim to be.

In summary, every page requiring authentication should validate the user prior to any other processing. A convenient method for doing this is to have a common function which checks that the user’s authentication information, typically stored in session variables, against a flat file, a database, or any number of other methods. Once the user’s identity has been determined and validated, the rest of the script can be allowed to execute. If the information is not valid, the script can forward the user to a login page or simply terminate execution with an error message.