PHP Cookies are very safe when your site uses HTTPS (the S is for Secured) with a sufficiently complex key in the SSL certificate. PHP instructs your browser's PHPSESSID cookie to contain the file name of the $_SESSION variable. Calling session_start();
loads the file directed to by the browser's PHPSESSID cookie into the $_SESSION variable. Nevertheless, it still is possible to impose an additional IP address validation by storing the user's IP address inside the session file. Observe.
<?php
session_start();
if (array_key_exists('V_CI', $_SESSION)) {
// Validate that an existing session is still from the same PC
if (
$_SESSION['V_CI'] !== $_SERVER['HTTP_CLIENT_IP'] ||
$_SESSION['V_XFF'] !== $_SERVER['HTTP_X_FORWARDED_FOR'] ||
$_SESSION['V_XF'] !== $_SERVER['HTTP_X_FORWARDED'] ||
$_SESSION['V_FF'] !== $_SERVER['HTTP_FORWARDED_FOR'] ||
$_SESSION['V_F'] !== $_SERVER['HTTP_FORWARDED'] ||
$_SESSION['V_RA'] !== $_SERVER['HTTP_REMOTE_ADDR'] ||
$_SESSION['V_UA'] !== $_SERVER['HTTP_USER_AGENT']
) session_regenerate_id( false );
}
if (!array_key_exists('V_CI', $_SESSION)) {
// we are filling a newly created key
$_SESSION['V_CI'] = $_SERVER['HTTP_CLIENT_IP'];
$_SESSION['V_XFF'] = $_SERVER['HTTP_X_FORWARDED_FOR'];
$_SESSION['V_XF'] = $_SERVER['HTTP_X_FORWARDED'];
$_SESSION['V_FF'] = $_SERVER['HTTP_FORWARDED_FOR'];
$_SESSION['V_F'] = $_SERVER['HTTP_FORWARDED'];
$_SESSION['V_RA'] = $_SERVER['HTTP_REMOTE_ADDR'];
$_SESSION['V_UA'] = $_SERVER['HTTP_USER_AGENT'];
}
I abbreviated all of the above session variables to conserve space on your hard disk. This will especially come in handy if you apply the above PHP code to every user that visits your website.
Obviously, the above code will not do diddly if someone gets direct access to your server computer because they could bypass whatever security measures you have in place. Aside from this problem, the code above does take security to the next level in whatever PHP script you drop the code into.
Notice that the code above also stores the user agent string. In my mind, the user agent string is far too easy to fake. Additionally, this user agent string will change when the user updates their browser. Additionally, user agent strings are usually very long, so they bloat the size of the session files. Thus, I suggest using the below code which does not compare the user agent string.
<?php
session_start();
if (array_key_exists('V_CI', $_SESSION)) {
// Validate that an existing session is still from the same PC
if (
$_SESSION['V_CI'] !== $_SERVER['HTTP_CLIENT_IP'] ||
$_SESSION['V_XFF'] !== $_SERVER['HTTP_X_FORWARDED_FOR'] ||
$_SESSION['V_XF'] !== $_SERVER['HTTP_X_FORWARDED'] ||
$_SESSION['V_FF'] !== $_SERVER['HTTP_FORWARDED_FOR'] ||
$_SESSION['V_F'] !== $_SERVER['HTTP_FORWARDED'] ||
$_SESSION['V_RA'] !== $_SERVER['HTTP_REMOTE_ADDR']
) session_regenerate_id( false );
}
if (!array_key_exists('V_CI', $_SESSION)) {
// we are filling a newly created key
$_SESSION['V_CI'] = $_SERVER['HTTP_CLIENT_IP'];
$_SESSION['V_XFF'] = $_SERVER['HTTP_X_FORWARDED_FOR'];
$_SESSION['V_XF'] = $_SERVER['HTTP_X_FORWARDED'];
$_SESSION['V_FF'] = $_SERVER['HTTP_FORWARDED_FOR'];
$_SESSION['V_F'] = $_SERVER['HTTP_FORWARDED'];
$_SESSION['V_RA'] = $_SERVER['HTTP_REMOTE_ADDR'];
}