SESSION机制及其安全管理

很多关于PHP的书都会介绍SESSION机制.但是往往介绍如何去使用,很少提及SESSION安全性雷区,如何正确的使用SESSION?

SESSION机制

为什么要有SESSION机制?

因为,HTTP协议是无状态的,SESSION是用于维持访问状态,区分访问者的机制.比如在没有SESSION机制的前提下,想让服务器完成每个访问者的个性化定制是不可能是事情.你可能会想到使用IP和UA等信息区分客户,但是在局域网通过网关连接广域网的时候就不能起作用,而且一旦涉及到登录等敏感操作的时候需要更加稳定,难以伪造的用户区分机制,这样就有了SESSION.

什么是SESSION机制?

SESSION是将用户信息存储在服务器上,并通过Cookie或URL传递一个SessionID给用户,与该用户的信息一一对应的机制.用户通过传递SessionID向服务器表明自己的身份.服务器通过传来的SessionID,确定用户的状态.

表面上看,SESSION是非常巧妙的安全的设计,它使得HTTP可以维持状态,在用户体验上得分不少.但是,不正确的使用SESSION会使得网站安全岌岌可危,甚至造成不可挽回的失误.

SESSION安全

由于SessionID就像一把钥匙,获取了这把钥匙,就获取了用户数据.所以,SESSION的攻击就集中在如何获取SessionID上.基本上可以分为两种情况:

  1. 截获SessionID
  2. 诱导持有SessionID的用户执行特定操作

截获SessionID只能作用于设计不良的网站上,或者浏览器安全性存在巨大隐患的场景中.第二条是CSRF攻击的基础.基本上对于SESSION低成本的攻击都可以归类为这两种.

值得注意的是CSRF攻击的预防,不能仅仅止步于对SESSION的管理上,而是要通过表单中插入Token等,只是CSRF攻击以SESSION机制作为其根本.

PHP中SESSION的安全性

以下是常见的几种攻击和防范方法:

1. 关闭session.use_trans_sid

session.use_trans_sid: 在没有开启cookie的网站上允许通过URL传递SessionID.

开启这项配置,攻击者可以通过迷惑用户使用带有SessionID的的URL访问目标网站,之后用户在此SessionID下留有的信息,对于攻击者都是可见的.

在关闭这项配置的时候也可以使用JavaScript读取用户cookie中的SessionID.

例如:
A网站存在上述缺陷,小明点击黑客提供的链接a.com/?ssid=aabbcc访问了网站A,并在该网站登录,然后退出.这时黑客在使用链接a.com/?ssid=aabbcc登录后发现正处于登录状态,然后进行非法操作.

如果a.com网站关闭session.use_trans_sid配置,这样小明就无法登录,因为禁用了cookie.这样虽然对用户体验很不友好,但是绝大多数成熟网站都是这样做的.更进一步,应该开启session.use_strict_mode防止类似aabbcc这种未初始化的SessionID被使用,但是黑客可以将aabbcc改为a.com正常生成的SessionID,虽然作用有限,但是强烈建议开启这个配置.

假设a.com关闭了session.use_trans_sid配置,小明也可以正常接收cookie,那么攻击还会发生吗?

2. 开启session.cookie_httponly

网站a.com强制要求用户使用cookie来接收SessionID.

这时黑客升级了自己的攻击方案,在a.com通过XSS,在小明经常访问的页面评论区注入了JavaScript脚本用来直接获取小明浏览器中的cookie数据.虽然攻击难度加大,但是小明会在毫不知情的情况下暴露SessionID.

网站a.com只要对用户的评论信息做转义就可以有效的防止XSS注入.这不属于SESSION安全的范畴,但是的确可以通过这种方法保护SessionID.最主要的是开启session.cookie_httponly,杜绝使用JavaScript读取cookie.但是这个设置有个前提,就是用户使用高质量的浏览器,因为这个设置只能起到通知浏览器的作用,具体逻辑是由浏览器实现的.

3.在表单中使用Token

网站a.com做了XSS防范,并且开启了session.cookie_httponly.

黑客继续升级自己的攻击方案,在自己的网站上使用JavaScript恶意向目标网站a.com提交表单,一旦小明开始向a.com提交,a.com索要SessionID,小明的浏览器就自动将SessionID传给a.com,根据表单的含义,黑客就可以简介的控制小明在a.com上的行为.这种方法就是常见CSRF的一种.

那么,a.com如何甄别提交表单的是小明还是黑客呢?就是在表单中加入隐藏的一个Token,或使用验证码,如果是黑客,这个Token是无法伪造的,而且验证码攻破难度在现如今几乎是不可能的.这样,a.com检测到的Token或验证码错误的情况下,不予操作.

其他工作

这样一来,a.com在面对常规的攻击时就能很好的应对了.还有一些工作也要跟进,防患于未然.

1. 尽可能频繁的更换SessionID

比如在登录成功后为用户更换SessionID.

2. 敏感操作时二次验证

例如支付时要求输入密码或验证码.

3. 编写可靠的SESSION回收程序

PHP的SESSION在过期后不会被立即删除,而是要等待gc(垃圾清理)程序不定期清理.高可靠性的网站应该尽量自己实现gc,在SESSION过期后尽可能快的删除.

发表新评论