if (user_auth()) {
$access = true;
}
if ($access) {
do_sensitive_things();
}
This could be exploited by tacking an ?access=true to the
end of the url, and the if ($access) test would be passed
despite the user_auth() function returning false. This
hole could be closed easily by adding a $access = false; at
the top of the script, but not all security holes are this easy to spot.
Thankfully, PHP now defaults the register_globals option to
off. This setting would pass the access variable sent by the url to the
script as $_GET[access] rather than just
$access. This closes off many of these types of
vulnerabilities, but when writing PHP code, especially code for
distribution, you should never assume that this option will be set
correctly, and always initialize your PHP variables. Users in a shared
hosting environment may not have the ability to set these options to
their most secure setting.
register_globals to off, but never write
code that assumes this setting.
ini_get() function to determine if
register_globals is set at runtime.
Another common cause of PHP application holes is improper sanitization
of user provided data. For example, if you allow a user to fill out a
form and then pass data from a field on that form to a function like
system() or exec() the data could contain
something malicious, like an ; rm -rf * command tacked onto it.
Another related but common security flaw in PHP applications is a SQL
injection vulnerability. The magic_quotes_gpc option can
mitigate this, but as with register_globals you should not
assume this setting is on.
For example, in your PHP script you might ask the user for a user id and password, and then check for the user by passing the database a query.
SELECT * FROM users WHERE name='$username' AND pass='$password';
However, if the user logging in is malicious and devious, he may enter
the following as his password:
' OR '1'='1
This causes your query to become:
SELECT * FROM users WHERE name='known_user' AND pass=' OR '1'='1';
The user has just logged in with no password, and your application has
been penetrated. To avoid this, check for the status of
magic_quotes_gpc() using the ini_get()
function and if it is disabled, pass all user input that must be
included in a query through addslashes(). This will escape
the single or double quotes in the user input with backslashes, thereby
thwarting the attempted SQL injection attack.
magic_quotes_gpc, but don't assume it is on or
depend on it.
addslashes() function should be used on user data
passed to SQL queries.
The PHP online manual
contains an entire
chapter on PHP security. It's an excellent resource, and goes into
much more detail on the PHP security issues I've discussed in this
article. Until next time, stay secure, and don't blindly trust any user
provided data.
--
Pax Dickinson has over ten years of experience in systems administration and software development on a wide variety of hardware and software platforms. He is currently employed by Guardian Digital as a systems programmer where he develops and implements security solutions using EnGarde Secure Linux. His experience includes UNIX and Windows systems engineering and support at Prudential Insurance, Guardian Life Insurance, Philips Electronics and a wide variety of small business consulting roles.