I have a little write-up on this in my phpauth code (www.phpauth.com).
Here are the main points:
php_admin_flag register_globals off
php_admin_flag magic_quotes_gpc off
php_admin_flag magic_quotes_runtime off
Use sprintf to put the queries together:
$query=sprintf("select * from users where username='%s'",addslashes($username));
Here's my writeup from phpauth:
2. Magic Quotes:
When magic quotes are turned on, all "external" data (get, post, cookie)
variables will have a backslash character "\" added before any double or
single quotes. The reason for this is that if you're going to use the data
in any sort of database access, you'll have to do that anyway, and the PHP
authors are helping you out with security by forcing it. As an example:
select * from user where username="$username";
Where "username" is something that the user has typed into a form variable.
Now, a smart user can enter this for $username:
sldkfjsdlk" or username="administrator
Look at what will happen if that is substituted into the above select
statement. With magic quotes, that data is automatically turned into this:
sldkfjsdlk\" or username=\"administrator
Now, with the quotes properly escaped, the select is safe. So why do I
recommend (require if you use my software) that you disable such a
wonderful feature?
First, it doesn't cover the entire problem, which is people entering bad
data. While adding backslashes does keep the user from seeing the wrong
record in the above example, it doesn't solve the real problem of
'sldkfjsdlk" or username="administrator' being an invalid username. The
proper way to handle that is to use a regular expression to make sure that
the input data is of the proper format, and if so, use "addslashes" to
escape any quotation marks and then proceed with the select. Otherwise,
give the user an error and skip the select.
All data that is entered should be checked like that. Numbers should be
checked with "is_numeric" before being accepted. Strings should be checked
with a regular expression if there is a format to be followed. This
includes data in hidden fields and <select> controls, which can easily be
spoofed by advanced users.
The second problem with magic quotes is that almost invariably, if the
quotes are automatically added, they will need to be removed elsewhere.
For instance, if the posted data is put back in the form, you'll have to
use "stripslashes" to clean it up first. Given that there's no more work
involved, it makes more sense to use the intuitive method.
<input type="text" name="sample" value="<?php print htmlentities($_POST['sample']);
?>">
And the third problem with magic quotes is that, while they work for
database access, we're not always performing database access. They're a
real pain when you're just trying to write your data to a file and have to
use stripslashes everywhere.
3. Register Globals
Around PHP 4.1, the new $_POST, $_GET, $_COOKIES, $_REQUEST, $_SESSION, and
$_SERVER variables were added. These are available without declaration in
any context, and should be used.
Previously, we used "register_globals" to cause all get, post, and cookie
variables (as well as others) to be automatically registered in the global
variable space. I, as well as many others, recognized this as a potential
security risk as it was easy for any web user to pollute your global
variable space with anything that they wished. And while I suggest that
you always initialize your variables, anyway, turning off register_globals
will remove one more potential security vulnerability.
This point was underscored when a vulnerability was found in phplib which
would allow a malicious web site user to change the value of libdir and
potentially read other files on the system (intential vagueness).
I generally process request variables at the top like this:
if ($_POST['numeric_value'] && is_numeric($_POST['numeric_value'])) {
$numeric_value=$_POST['numeric_value'];
}
if ($_POST['text_value'] && preg_match('/whatever/',$_POST['text_value']) {
$text_value=$_POST['text_value'];
}
if (isset($numeric_value) && isset($text_value)) {
// do your processing here
}
Don't do any processing unless it is safe.
Let me add a bit to this. These two sections tackle the same problem from two
angles, but the problem is essentially bad data entered on a form. You should
be in the habit of checking all data entered on forms and don't allow it into
your program unless it passes a test. I don't even use "is_numeric" anymore;
I use preg_match to grab any contiguous digits that may be in there. And if
it goes into a query, I use %d in my format string.
On the other hand, make sure to always run text data through htmlentities
before outputting it.
This problem isn't a php problem, it's just the nature of the web. Perl is
great because of tainting. In php, you just have to use self-discipline :)
Michael
--
Michael Darrin Chaney
[EMAIL PROTECTED]
http://www.michaelchaney.com/
--
Philippine Linux Users' Group (PLUG) Mailing List
[EMAIL PROTECTED] (#PLUG @ irc.free.net.ph)
Official Website: http://plug.linux.org.ph
Searchable Archives: http://marc.free.net.ph
.
To leave, go to http://lists.q-linux.com/mailman/listinfo/plug
.
Are you a Linux newbie? To join the newbie list, go to
http://lists.q-linux.com/mailman/listinfo/ph-linux-newbie