Scenario:
session
Question:
Is this a strong enough security measure by itself, or should I
========
(Incidentally, while I was researching this question, this wiki is a fantastic read.)
It is enough to store just user login (or user id) in the session.
To prevent session fixation/hijacking everything you need is just to implement simple algorythm (pseudocode):
if (!isset($_SESSION['hash']) {
$_SESSION['hash'] = md5(!empty($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : 'no ua');
} else if ($_SESSION['hash'] != md5(!empty($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : 'no ua')) {
session_regenerate_id();
$_SESSION = array();
$_SESSION['hash'] = md5(!empty($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : 'no ua');
}
You could move the hash calculation into some function to prevent of duplication, i've just shown a sketch of possible protection.
This is how I implemented this kind of protection in my kohana session class:
abstract class Session extends Kohana_Session
{
public function read($id = null)
{
parent::read($id);
$hash = $this->calculateHash();
$sessionHash = $this->get('session_fixation');
if (!$sessionHash) {
$this->set('session_fixation', $hash);
} elseif ($sessionHash != $hash) {
$this->regenerate();
$_SESSION = array();
$this->set('session_fixation', $hash);
}
}
private function calculateHash()
{
$ip = !empty($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '127.0.0.1';
$ua = !empty($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : 'no ua';
$charset = !empty($_SERVER['HTTP_ACCEPT_CHARSET']) ? $_SERVER['HTTP_ACCEPT_CHARSET'] : 'no charset';
$ip = substr($ip, 0, strrpos($ip, '.') - 1);
return md5($ua . $ip . $charset);
}
}
Don't try to write your own session scheme, PHP will do it better.
yes you can add more information to your $_SESSION to help prevent session hijacking
for example I generate a fingerprint by combining a secret phrase or random data with the user agent and the session_id() and hash it all. To hijack a session the user would need to figure out a valid session_id, and the hash of the fingerprint. it will look like this. This is a good read
$_SESSION['fingerprint'] = md5('somethingSecret' . $_SERVER['HTTP_USER_AGENT']. session_id());
then you would validate the session like
$check_print = md5('somethingSecret' . $_SERVER['HTTP_USER_AGENT']. session_id());
if($check_print != $_SESSION['fingerprint'] || $_SESSION['authenticated']){
//invalid session
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With