Não há como impedir que a sessão seja invadida 100%, mas com alguma abordagem podemos reduzir o tempo de um invasor invadir a sessão.
Método para impedir o hijaking da sessão:
1 - sempre use sessão com certificado ssl;
2 - envie o cookie da sessão apenas com a ativação definida para true (evite que o javascript acesse o cookie da sessão)
2 - use o ID de regeneração da sessão no login e logout (nota: não use a regeneração de sessão em cada solicitação, porque se você tiver uma solicitação ajax consecutiva, poderá criar várias sessões.)
3 - definir um tempo limite da sessão
4 - armazene o agente do usuário do navegador em uma variável $ _SESSION e compare com $ _SERVER ['HTTP_USER_AGENT'] a cada solicitação
5 - defina um cookie de token e defina o tempo de expiração desse cookie para 0 (até que o navegador seja fechado). Gere novamente o valor do cookie para cada solicitação (para a solicitação do ajax, não gere novamente o cookie do token). EX:
//set a token cookie if one not exist
if(!isset($_COOKIE['user_token'])){
//generate a random string for cookie value
$cookie_token = bin2hex(mcrypt_create_iv('16' , MCRYPT_DEV_URANDOM));
//set a session variable with that random string
$_SESSION['user_token'] = $cookie_token;
//set cookie with rand value
setcookie('user_token', $cookie_token , 0 , '/' , 'donategame.com' , true , true);
}
//set a sesison variable with request of www.example.com
if(!isset($_SESSION['request'])){
$_SESSION['request'] = -1;
}
//increment $_SESSION['request'] with 1 for each request at www.example.com
$_SESSION['request']++;
//verify if $_SESSION['user_token'] it's equal with $_COOKIE['user_token'] only for $_SESSION['request'] > 0
if($_SESSION['request'] > 0){
// if it's equal then regenerete value of token cookie if not then destroy_session
if($_SESSION['user_token'] === $_COOKIE['user_token']){
$cookie_token = bin2hex(mcrypt_create_iv('16' , MCRYPT_DEV_URANDOM));
$_SESSION['user_token'] = $cookie_token;
setcookie('user_token', $cookie_token , 0 , '/' , 'donategame.com' , true , true);
}else{
//code for session_destroy
}
}
//prevent session hijaking with browser user agent
if(!isset($_SESSION['user_agent'])){
$_SESSION['user_agent'] = $_SERVER['HTTP_USER_AGENT'];
}
if($_SESSION['user_agent'] != $_SERVER['HTTP_USER_AGENT']){
die('session hijaking - user agent');
}
note Observação: não gere novamente o cookie de token com solicitação do ajax. note: o código acima é um exemplo. nota: se os usuários fizerem logout, o token do cookie deverá ser destruído, assim como a sessão
6 - não é uma boa abordagem usar o ip do usuário para impedir o hijaking da sessão, pois alguns ip do usuário mudam a cada solicitação. QUE AFETA USUÁRIOS VALIDOS
7 - pessoalmente eu armazeno dados da sessão no banco de dados, cabe a você qual método você adota
Se você encontrar algum erro na minha abordagem, corrija-me. Se você tiver mais maneiras de impedir a sessão de hyjaking, informe-me.