PHP Security
This page covers the following topics as related to web application security using PHP.
Register Globals
Arguably the most common source of vulnerabilities in PHP applications.
becomes...
This is bad because there is no way to determine the input source. Uninitialized variables can be injected via user input. All input parameters are translated to variables.
In addition to being a security hazard, it is an option that may not not be available on all servers. Best practices are to use
or
Session Management
Session attacks can not be prevented by filtering input and escaping output.
OWASP recommondations for PHP session management
Session Fixation
Session Fixation is an attack technique that forces a user's session ID to an explicit value. Depending on the functionality of the target web site, a number of techniques can be utilized to "fix" the session ID value. These techniques range from Cross-Site Scripting (XSS) exploits to peppering the web site with previously made HTTP requests. After a user's session ID has been fixed, the attacker will wait for them to login. Once a user does so, the attacker uses the predefined session ID value to assume their online identity.
Preventing Session Fixation
- Do not accept session identifiers from GET/POST variables:
Session identifiers in URL (query string, GET variables) or POST variables are not recommended as it simplifies this attack. It is easy to make links on forms which set GET/POST variables.
- Regenerate the SID on each request:
In PHP use session_regenerate_id(). Every time a user's access level changes, it is necessary to regenerate the session identifier. This means that although an attacker may trick a user into accepting a known SID, the SID will be invalid when the attacker attempts to re-use the SID. For example...
if (authenticate())
{
session_regenerate_id();
}
- Accept only server generated SID:
One way to improve security is to not accept session identifiers that were not generated by the server/
if(!isset($_SESSION['SERVER_GENERATED_SID'])) {
session_destroy();
}
session_regenerate_id( );
$_SESSION['SERVER_GENERATED_SID']=true;
Session Hijacking
Session hijacking is a generic term used to describe any means by which an attacker gains a user's valid session identifier (rather than providing one of her own). For example, suppose the user logs in. If the session identifier is regnerated, they have a new session ID. What if an attacker discovers this new ID and attempts to use it to gain access through that user's session? We now need to use another method to identify the user.
One way to idenify the user in addition to the session ID is to check various request headers sent by the client. One request header that is particularly helpful and does not change between requests is the User-Agent header. It is unlikely that a legitimate user will change from one browser to another while using the same session. Because of this you can use User-Agent to determine if a possible session hijacking attempt is being made.
$_SESSION['user_agent'] = $_SERVER['HTTP_USER_AGENT'];
Then, on subsequent page loads, check to ensure that the User-Agen has not changed. If it has changed, then it is cause for concern and you should make the user log in again.
if ($_SESSION['user_agent'] != $_SERVER['HTTP_USER_AGENT'])
{
exit;
}
Checking Input
Validating Numbers
If you expect a variable to always contain a numeric value, one simple way to achieve this validation is to use casting.
if (!empty($_GET['id']))
$id = (int)$_GET['id'];
else
$id = 0;
if (!empty($_GET['price']))
$price = (float)$_GET['price'];
else
$price = 0;
Validating Strings
PHP comes with a ctype extension that offers a very quick mechanism for validating string input. Here are some examples:
if (!ctype_alnum($_GET['login'])) {
echo "Only A-Za-z0-9 are allowed.";
}
if (!ctype_alpha($_GET['captcha'])){
echo "Only A-Za-z are allowed.";
}
if (!ctype_xdigit($_GET['color'])){
echo "Only hexadecimal values are allowed.";
}
|