-
PHP Security Primer Part 1
Posted on March 28th, 2009 No commentsThe ability to pull information from many sources is often what makes PHP a powerful and attractive solution. By not being a diligent developer, though, and failing to make the assumption that this input is malicious (or otherwise dangerous), you can
open PHP to all sorts of attacks. Ensuring that incoming data doesn’t compromise your application is by far one of the most important tasks when developing any dynamic web application, but it is also one of the tasks most neglected. This article will cover some common problems and situations, and how to cover your assets.
Common website inputs
Arguably the four most common inputs to any web application are GET data, POST data, cookie data, and session data. If you are reading this article, you are
most likely familiar with all or most of these methods of input, but I’ll review them here.
GET data
This type of data is attached to the URL, like so:
http://www.example.com/index.php?param1=value1¶m2=value2
It usually comes from either a hyperlink or a form submission. You can find these values in associative array form in the $_GET superglobal.
POST data
POST data enters your script as part of the HTTP request body, and can contain arbitrary amounts (almost) and types of data without issue (such as files). This type of
data is not visible in the URL, making it perfect for login forms or other forms where some obscurity would be helpful. With the exception of uploaded files, all POST
data ends up in the $_POST superglobal.
Cookie data
A cookie is some small piece of information that a web server may ask the browser to store locally for a period of time. Subsequent accesses to that site will pass the
stored cookie data back to the server, where it will be made available to the application being accessed through the $_COOKIE superglobal. Cookies are often
used to somehow try and identify a particular user over the web. This is, for example, how websites can automatically log you in when you return days later. In that
case, the cookie would likely be some sort of unique identifier that is really just a key to a session record stored somewhere on the server. Sessions are discussed next.
Session data
When somebody accesses your site, you can give him or her a unique ID, a so called session ID. This ID can either be stored in a cookie on the user’s computer, or
passed around on every request in the GET or POST data. This session ID is usually a key a larger set of information that is stored on the server, which is made available
to the accessed application through the $_SESSION superglobal. This session data might contain pointers to items currently in your shopping cart, or a flag as to
whether or not you are logged in to the site. Now let’s take a look at a few ways to ensure that input coming through these channels does not adversely affect our script.
register_globals
The first thing to do is to make sure that the register_globals setting in your php.ini file is OFF. This shouldn’t be an issue for most users, since all versions
of PHP from 4.2 on have shipped with this option turned off by default. There are cases, though, where out of convenience, necessity, or ignorance register_globals was re-enabled.
The register_globals setting determines whether or not variables in the superglobal arrays also appear as global variables. For instance, an element named “foo” (when submitted) shows up either in $_GET[‘foo’] or $_POST[‘foo’]. With register_globals on, the variable $foo will also be set in the global scope of your script.
This feature helped make PHP very popular from an ease-of-use standpoint, but it introduces a host of very serious security problems. By passing in the appropriate
variable in the GET or POST data, a malicious user can effectively inject values into your script. Depending on the intent, this can either affect operation of your
script or cause confusion as to where the value of a variable came from. For instance, did the value of $foo come from a GET injection, or from cookie data?.
There are precautions that can be taken to reduce the danger of this variable injection, but it is safer to simply turn register_globals off and access all GET and POST
data through their respective superglobal variables.
magic_quotes_gpc
By turning on the magic_quotes_gpc setting in your php.ini configuration file, all incoming GET, POST, and cookie data will have single quotes, double quotes,
backslashes, and NULs escaped. This is most useful when going on to insert this data into a database. It may not be as useful when outputting this data to the
browser. Consider this example:
A request comes in with this URL:
http://www.example.com/myscript.php?sitename=John’s%20Site
In the GET data there is an apostrophe. With magic_quotes_gpc off, this data comes in as “John’s Site”. Conversely, with magic_quotes_gpc on, it comes in as “John\’s Site”.
Why does a little tiny apostrophe incite such fear? If you are producing SQL queries with this input data, you can end up creating huge security holes without
even realizing it.
Suppose, for example:
SELECT * FROM sites WHERE sitename=’John’s Site’
This will give us some sort of error, which is undesirable. If an unwanted visitor has some bad intentions, though, he may be able to fool the system. What if our
$_GET[‘sitename’] variable contained the value “John’ OR 1”?
SELECT * FROM sites WHERE sitename=’John’ OR 1
This query might give the malicious user a complete list of the sites table, thereby giving him all kinds of interesting information that he was never meant to see.
Another interesting setting, magic_quotes_runtime, specifies whether functions that return data from external sources, such as databases or files, should have their results escaped also.
Leave a reply



Recent Comments