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

Reply via email to