paul burney dot com
Stay gold, Ponyboy...
PHP Security and Efficiency
I've been programming in PHP for a few years now (since 3.06 or so), and I'd like to share what are probably considered radical thoughts.
Functions
Functions are great for certain things: Displaying things based on a few variables, calculating numbers based on a few arguments, displaying custom lines, etc. However, if you need to define a million global variables, why bother putting it in a function?
Also, imagine a web application with 20 more or less independent "sheets" that a user interacts with. Now imagine that the main body of the code contains 20 large functions to generate those pages. If every single function is parsed each time a page is displayed that uses just one or two functions to generate it, that's a lot of waste in my opinion.
I've found that in general, because of the nature of web applications, it's more efficient to use a bunch of include files rather than one huge function file. If you are planning on porting to web application to another language (Java) or convert it to a standalone application (via phpGtk for example), you may wish to stick to the function file because the whole app will be read into memory once instead of the multiple times a web application is.
Auto-Registered Global Variables
Global variables are one of the really nice things about PHP. They make it an incredibly easy language to use. I've recently been waffling about whether it is better/more secure to have register_globals set to Off in the php.ini file.
I think I've come more to Rasmus' understanding of the issue now. It depends on your coding skill wheter or not register globals is necessary or important.
Basically, if you're in the practice of initializing all variables within your code, register globals is a good thing to have on. It makes it easier to access the variables and the code looks a bit cleaner. As long as you have $loggedin = 0; at the top of the script, there isn't a problem with code like:
<?php
if ($loggedin) {
give_user_all_access();
}
?>
If you hadn't initialized the variable, you would be in trouble of course. In summary, I agree with the move to make register_globals default to off in the configuration because there are a lot of newbies out there. I don't agree, however, that register_globals is inherently unsafe.
Magic Quotes GPC
No matter what anyone tells you, don't turn off magic_quotes_gpc. Basically, it adds backslashes to any quotes or null characters in user supplied data. This is vitally important if you are doing anything with the data other than displaying it back to the screen.
Most importantly, magic_quotes_gpc helps to protect you against SQL Injection attacks. Even though you can just call the addslashes() function on every query, if you miss once it could be too late. Here's an example:
$query = 'SELECT * FROM secret_medications WHERE password="' . $pass. '"';
Now, let's say your malicious user uses the following password: hax0r3d" OR 1="1
Without Magic Quotes: SELECT * FROM secret_medications WHERE password="hax0r3d" OR 1="1"
User gets every user's secret_medications which she can use for blackmail or worse.
With Magic Quotes: SELECT * FROM secret_medications WHERE password="hax0r3d\" OR 1=\"1"
User gets an error message (no records found), foiling her dastardly attempt.
Important: You must quote all values in MySQL SELECT statements, even numerics, because if not you'll be subject to many more SQL Injection attacks.
So the drawback to magic_quotes_gpc? Well, if you want to display the user supplied data back to the user, you need to call stripslashes() and htmlspecialchars() or Tom O'Malley will be Tom O\'Malley. Of course, you should be checking your data for Cross Site Scripting (XSS) attacks anyway.