Some of the best tips I have found in PHP...
Register Globals
Register Globals is now turned off by default, and most coders are getting used to implementing $_POST['variable'] and so on into their scripts. Note for Windows users: If your php.ini file still sets "register_globals = On" because you kept your php.ini settings on an upgrade then it may be a good idea to change it - even if it is just on your home or local machine for your own personal use (It is good practice to get into secure habits).
What if you can not change the setting though? You may be using an ISP/host which sets "register_globals = On" for compatibility reasons and refuse to change it. Well shame on your ISP, however there are things you can do about it! First you may want to check the status of the register_globals setting, simply issue the phpinfo() function on the server and check the register_globals value in the PHP Core table.
If it is "On" and you can not change it to "Off" by editing the setting, then you have a few options to make your code more secure.
1. Put all your code into a function, then call the function. The scope of variables in functions will save the day for you.
2. Manually use a function to unregister globals. If you first save the superglobals, you can then copy them back after the unregistering is done.
PHP Code:
function unregister_globals()
{
// Save the existing superglobals first
$REQUEST = $_REQUEST;
$GET = $_GET;
$POST = $_POST;
$COOKIE = $_COOKIE;
if (isset($_SESSION))
{
$SESSION = $_SESSION;
}
$FILES = $_FILES;
$ENV = $_ENV;
$SERVER = $_SERVER;
// Unset the $GLOBALS array (clear all)
foreach($GLOBALS as $key => $value)
{
if ($key != 'GLOBALS')
{
unset($GLOBALS[$key]);
}
}
// Re-assign the saved superglobals again
$_REQUEST = $REQUEST;
$_GET = $GET;
$_POST = $POST;
$_COOKIE = $COOKIE;
if (isset($SESSION))
{
$_SESSION = $SESSION;
}
$_FILES = $FILES;
$_ENV = $ENV;
$_SERVER = $SERVER;
}
unregister_globals();
Apologies to Theo Spears of php|architect magazine (http://www.phparch.com). You can read his two other methods for solving the register globals problem and also other ideas for "Writing Secure PHP Code" in the January 2003, Volume II, Issue 1 edition of the magazine, which is available FREE.
Magic Quotes
Another configurable setting which may affect your scripts is Magic Quotes - both GPC (for incoming Get, Post and Cookie data) and Runtime (for runtime-generated data, e.g. data from SQL, from exec(), etc.) Check the status of Magic Quotes with this:
PHP Code:
echo 'GPC Status: ' . get_magic_quotes_gpc() . '<br />';
echo 'Runtime Status: ' . get_magic_quotes_runtime();
// 1 = On
// 0 = Off
Use a function that will automatically call "addslashes" to your SQL queries if Magic Quotes is off. Here's one for GPC quotes:
PHP Code:
define("MAGIC_QUOTES_STAT_GPC", get_magic_quotes_gpc());
function auto_slash($str)
{
if (1 == MAGIC_QUOTES_STAT_GPC)
{
return $str;
}
else
{
return addslashes($str);
}
}
Then adapt your SQL queries accordingly...
PHP Code:
// Here is an UPDATE query using a $_POST value
$table = 'my_table';
$field = auto_slash($_POST['my_field']);
$sql = 'UPDATE ' . $table .
'SET my_field = ' . $field .
'\'';
// Note: a backslash is missing here! '
// See note at end of this post.
// And here is a SELECT query using the same
$id = auto_slash($_POST['my_id']);
$column = 'my_column';
$table = 'my_table';
$sql = 'SELECT ' . $column .
'FROM ' . $table .
'WHERE id = \'' . $id .
'\'';
// Note: a backslash is missing here!
Databases and Tables
When putting SQL queries into your PHP scripts, you should create a seperate file which sets the names of each database or table. This file can then be included when required, and if any database or table name needs to be changed, then you only need to make one alteration - not many! This is very useful when you are using scripts from other people which create databases/tables, as their script may create a new database/table with the same name as one you already have.
Example configuration file:
PHP Code:
// Database Table Names
$conf['tbl']['books'] = 'book_names';
$conf['tbl']['authors'] = 'writers';
Any query can then use the defined names as so:
PHP Code:
$table = "$conf['tbl']['books']";
$field = 'field_value'
$sql = 'UPDATE ' . $table .
'SET my_field = ' . $field .
'\'';
// Note: a backslash is missing here!'
$table = "$conf['tbl']['authors']";
$field = 'field_value'
$sql = 'UPDATE ' . $table .
'SET my_field = ' . $field .
'\'';
// Note: a backslash is missing here!
NOTE: The VB Code in this forum keeps removing a backslash from the PHP source code.
All lines reading
' ' ' ;
should in fact read
' \ ' ' ;
Bookmarks