Session定置攻击的过程和预防

问题

确保用户的session标识符不会由第三方提供,例如挟持了用户的session的攻击者

方案

只要用户的授权范围改变,如成功登陆后,就通过session_regenerate_id()来重新生成session标识符

<?php
    session_regenerate_id();
    $_SESSION[‘logged_in’] = true;
?>

Session ID 变换

如上图,用户本次登陆时传递给服务器的cookies中的session id是 4tj1583c1nplkkf80oa2ikqf22。当验证成功后,利用session_regenerate_id()函数重新分配一个session id 9kehkhf5m900tqefbee97ho5n4,存在cookies中传递给客户端。

在默认情况下,PHP可以接受来自cookies或URL中的session标识符。而攻击者可能会欺骗受害人点击一个包含session标识符并指向到你的应用的链接:

[code]<a href="http://example.org/login.php?PHPSESSID=1234">点击</a>[/code]

点击了该链接的用户,其session标识符会被重置为1234。因此,攻击者在知道了这个用户的session标识符后,就可以通过使用相通的session标识符来尝试劫持用户的会话。

例子

  1. 首先,攻击者在这种情况下也是一个合法用户,登录到服务器
  2. 服务器向攻击者发送一个发送一个Session ID 1234
  3. 攻击者向用户发送超链接http://online.worldbank.dom/login.jsp?sessionid=1234,并企图诱惑他去点击
  4. 服务器收到login.jsp?sessionid=1234的请求,因为web服务器已经创建了基于Session ID 1234的会话,所以不会重新创建Session ID
  5. 用户提供了他的账号密码,服务器授予他访问他的银行帐户的权限
  6. 因为知道Session ID,攻击者同样可以通过account.jsp?sessionid=1234访问并操作用户信息
    session定置攻击流程图

攻击过程

一般来说,会话固定攻击是一个三个步骤,如下图所示

  1. 会话建立:首先,攻击者在目标服务器上设置一个所谓的Session陷阱,获得Session ID,或者选择一个通常任意Session ID用于攻击。在某些情况下,建立了陷阱会话需要维护(存活),通过重复发送请求引用来避免空闲会话超时。
  2. 会话定置:接下来,攻击者需要介绍他的SessionID给用户的浏览器,从而恢复他的会话。
  3. 进入会话:最后,攻击者必须等待,直到用户登录到目标服务器使用前面固定Session ID,然后进入用户的会话。
    session定置攻击过程

通过确保只要改变用户的授权范围就重新生成session标识符,可以有效地消除session定置攻击。如图一所示,PHP会自动更新存储的session数据并传送新的session标识符。——这算是比较简单有效的防止攻击的方法了


参考

  1. 《PHP 经典实例》
  2. session_fixation.pdf ——想了解更多关于session定制攻击的细节,戳它呗 (ps,可能之后有空会将其翻译)
坚持原创技术分享,您的支持将鼓励我继续创作!