Most of the PHP programmer used session to preserve certain data across subsequent pages. Nothing wrong with this method, since the web is stateless, most of the web developer used session to maintain a login site.
Usually, how we achieved this is to place a session cookie, in the form of a session ID (a 32 byte alpha-numeric string), on the client browser. When the client’s browser has cookies disabled, the session cannot be stored, so PHP propagates the session ID to the end of each URI on the page. So now, you may have noticed that an attacker may be capable of exploiting this vulnerability by constructing a malicious link containing script code embedded within this variable. PHP developer needs to take extra measurements to ensure the integrity of the session.
As a programmer, you need to ensure that a user’s session cannot be provided by attacker who seeks to hijack user’s session. One simple method to solve the problem is to regenerate session with session_regenerate_id() when there is a changes in user privileges, for example when user successfully login to the registered user’s restricted pages:
<?php
session_regenerate_id();
$_SESSION['logged_in'] = TRUE;
?>
By using session_regenerate_id(), you help to minimize session fixation dramatically.
The register globals directive has been disabled by default since PHP versions 4.2.0, let say if you are using PHP version 5.2.5, then most probably in your php.ini the variable for register_globals is set to OFF. By the way, this feature will be deprecated and removed for the future release of PHP version 6. Relying on this feature is highly discouraged.
Actually this feature does not posts any security vulnerability to PHP at all, but if PHP programmer misused it, it will create security risk to the web application.
When it is on, register_globals will inject all sorts of variables into your scripts, programmer uses variables not knowing where they came from, example request variables from HTML form. Since PHP does not required programmer to initialize variables, it make it easier to write insecure code. Let used a simple code, to make my point clearer:
<?php
function authenticate_user($username, $password) {
// make a connection to the database to verify if
// the username and password is in users table
$sql="SELECT * FROM users WHERE username='$username' and password='$password'";
$result=mysql_query($sql);
...
...
return $authorized_user; // return TRUE if the user exists
}
if (authenticate_user("kelvin", "xxxxx")) {
$authorized = TRUE;
}
if ($authorized) {
include "/very/important/data.php";
}
?>
With register_globals enabled, the page data.php can be access whitout authentication, all I need to do is request the page with ?authorized=1 in the query string. So you can see that the security vulnerability is the fault of the developer not PHP itself. So how to solved the problem with register_globals on? Simple, we just have to initialize variable $authorized=FALSE at the top of the code in our example above.
So to write a secure PHP code initialize every variables, or disable the register_globals. The second method is lot easier!
When PHP programmers create a form with javascript client side filtering to collect information from web users, but most of them forgotten or ignore to do server side data filtering. The reasons given by them are simply because it is not important or it is too time consuming to write long PHP code to get the job done.
They do not know how critical it is until you see the following example. You will later appreciate the necessity of data filtering.
Consider a html form located at http://www.secure.com/form.html, with a select options, which confirms user do accept the terms and conditions or not :
<form action="process.php" method="POST">
<select name="accept_terms">
<option value="accept">Accept</option>
<option value="refuse">Refuse</option>
</select>
<input type="submit"/>
</form>
Now imagine a attacker edit the above html and saves it as follows into their local box :
<form action="http://www.secure.com/process.php" method="POST">
<input type="text" name="accept_terms">
<input type="submit"/>
</form>
The form can be manipulated as desired, all the attacker needs is a web browser to post the form with the absolute URL where process.php resides.
This simple step will make it easy to eliminate client side restrictions. In this example, the attacker do not have to accept the terms and conditions. With a very simple procedure, any user can create a form that can be used to submit any data to the URL that processes the form.