因为有相同的session id包含在请求的Cookie头部中,所以相同的php session将会被访问到。但是,请求里的User-Agent头部跟先前的请求中的信息是不同的,系统是否可以假定这两个请求是同一个用户发出的?

 

像这种情况下,发现浏览器的头部改变了,但是不能肯定这是否是一次来自攻击者的请求的话,比较好的措施就是弹出一个要求输入密码的输入框让用户输入,这样的话,对用户体验的影响不会很大,又能很有效地防止攻击。

 

当然,你可以在系统中加入核查User-Agent头部的代码,类似Listing 3中的代码:

Listing 3:

<?php
session_start(); 
    
if (md5($_SERVER['HTTP_USER_AGENT']) != $_SESSION['HTTP_USER_AGENT']) 
{   /* 弹出密码输入框 */   exit;
} 
    
/* Rest of Code */ 
?>

当然,你先必须在第一次请求时,初始化session的时候,用MD5算法加密user agent信息并且保存在session中,类似下面listing4中的代码:

Listing 4:

<?php    
session_start();    
 
$_SESSION['HTTP_USER_AGENT'] = md5($_SERVER['HTTP_USER_AGENT']); 
?>

虽然不一定需要用MD5来加密这个User-Agent信息,但使用这种方式以后就不需要再过滤这个$_SERVER['HTTP_USER_AGENT']数据了。不然的话,在使用这个数据以前必须要进行数据过滤,因为任何来自客户端的数据都是不可信任的,必须要注意这一点。

 

在你检查这个User-Agent客户端头部信息以后,做为一个攻击者必须要完成两步才能劫持一个session:

  1. 获取一个合法的session id
  2. 包含一个相同的User-Agent头部在伪造的请求中

你可能会说,居然攻击者能获得有效的session id,那么以他的水平,伪造一个相同的User-Agent不是件难事。不错,但是我们可以说这至少给他添加了一些麻烦,在一定程度上也增加了session机制的安全性。

 

你应该也能想到了,既然我们可以检查User-Agent这个头部来加强安全性,那么不妨再利用其它的一些头部信息,把他们组合起来生成一个加密的token,并且让客户端在后续的请求中携带这个token!这样的话,攻击者基本上不可能猜测出这样一个token是怎么生成出来的。这好比你用信用卡在超市付款,一个你必须有信用卡(好比session id),另外你也必须输入一个支付密码(好比token),这有这两者都符合的情况下,你才能成功进入账号付款。 看下面一段代码:

<?php 
session_start(); 
$token = 'SHIFLETT' . $_SERVER['HTTP_USER_AGENT'];
$_SESSION['token'] = md5($token . session_id()); 
?>

注意:Accept这个头部不应该被用来生成token,因为有些浏览器会自动改变这个头部,当用户刷新浏览器的时候。

在你的验证机制中加入了这个非常难于猜测出来的token以后,安全性会得到很大的提升。假如这个token通过像session id一样的方式来进行传递,这种情况下,一个攻击者必须完成必要的3步来劫持用户的session:

  1. 获取一个合法的session ID
  2. 在请求中加入相同的User-Agent头部,用与生成token
  3. 在请求中携带被攻击者的token

这里面有个问题。如果session id以及token都是通过GET数据来传递的话,那么对于能获取session ID的攻击者,同样就能够获取到这个token。所以,比较安全靠谱的方式应该是利用两种不同的数据传递方式来分别传递session id以及token。例如,通过cookie来传递session id,然后通过GET数据来传递token。因此,假如攻击者通过某种手段获得了这个唯一的用户身份标识,也是不太可能同时轻松地获取到这个token,它相对来说依然是安全的。

 

还有很多的技术手段可以用来加强你的session机制的安全性。希望你在大致了解session的内部本质以后,可以设计出适合你的应用系统的验证机制,从而大大的提高系统的安全性。毕竟,你是最熟悉当下你开发的系统的开发者之一,可以根据实际情况来实施一些特有的,额外的安全措施。

总结

以上只是大概地描述了session的工作机制,以及简单地阐述了一些安全措施。但要记住,以上的方法都是能够加强安全性,不是说能够完全保护你的系统,希望读者自己再去调研相关内容。在这个调研过程中,相信你会学到很有实际使用价值的方案。