Today on Hacks From Pax we'll be discussing PHP web application security. PHP is a great language for rapidly developing web applications, and is very friendly to beginning programmers, but some of
its design can make it difficult to write web apps that are properly secure. We'll discuss some of the main security "gotchas" when developing PHP web applications, from proper user input sanitization to
avoiding SQL injection vulnerabilities.
Many PHP application vulnerabilities are caused by not properly initializing variables. This is an example of how PHP, by not requiring the developer to initialize a variable before using it, sacrifices
security for ease of use. For example, the following code is easily
exploitable.
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.
- Always initialize PHP variables before using them.
- Always set
register_globals to off, but never write
code that assumes this setting.
- You can use the
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.
- Never trust user provided data.
- Beware functions that launch system commands, think long and hard
about checking any data that is passed to them.
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.
- Use
magic_quotes_gpc, but don't assume it is on or
depend on it.
- The
addslashes() function should be used on user data
passed to SQL queries.
- Again, you simply cannot trust user provided data.
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.
Only registered users can write comments. Please login or register. Powered by AkoComment! |