Article
Write Secure Scripts with PHP 4.2!
For the longest time, one of the biggest selling points of PHP as a server-side scripting language was that values submitted from a form were automatically created as global variables for you. As of PHP 4.1, the makers of PHP recommended an alternate means of accessing submitted data. In PHP 4.2, they switched off the old way of doing things! As I'll explain in this article, these changes have been made in the name of security. Together, we'll explore the new features of PHP for handling form submissions and other data, and how they can be used to write more secure scripts.
What's wrong with this picture?
Consider the following PHP script, which grants access to a Web page only if the correct username and password are entered:
<?php
// Check the username and password
if ($username == 'kevin' and $password == 'secret')
$authorized = true;
?>
<?php if (!$authorized): ?>
<!-- Unauthorized users are prompted for their credentials -->
<p>Please enter your username and password:</p>
<form action="<?=$PHP_SELF?>" method="POST">
<p>Username: <input type="text" name="username" /><br />
Password: <input type="password" name="password" /><br />
<input type="submit" /></p>
</form>
<?php else: ?>
<!-- Super-Secret HTML content goes here -->
<?php endif; ?>
Okay, I'm sure about half the readers in the audience just rolled their eyes and said "That's so stupid -- I would never make a mistake like that!" But I guarantee that a good number of you are thinking "Hey, that's not bad. I should write that down!" And of course there's always the rather confused minority ("What's PHP?"). PHP was designed as a "nice and easy" scripting language that beginners can start to use in minutes; it should also protect those beginners from making scary mistakes like the one above.
For the record, the problem with the above script is that you can easily gain access to it without supplying the correct username and password. Simply type the address of the page into your browser with ?authorized=1 tacked on the end. Since PHP automatically creates a variable for every value submitted -- either from a form post, the URL query string, or a cookie -- this sets $authorized to 1 in the script and plops an unauthorized user right in front of the Colonel's secret recipe (apologies to the non-junk food eating readers who will not get that joke).
So, easy fix, right? Just set $authorized to false by default at the top of the script. The problem here is that a fix shouldn't have been necessary at all! $authorized is a variable created and used entirely within the script; why should the developer have to worry about protecting every single one of his or her variables from being overridden by values submitted by malicious users?
Kevin began developing for the Web in 1995 and is a highly respected technical author. He wrote