业务逻辑中的session问题

在之前的一些安全检测中,经常会遇到一些逻辑漏洞。有些问题可以看到有很多测试是否存在问题的方法,很少有说明漏洞产生的原因。在这儿简单说几个与session有关的问题以及原因。

在WEB中,很重要的一个特征就是每个HTTP请求都是独立的,服务器通过session和数据库记录当前请求的状态。session可以看作数据库的一层缓存,用户是不能直接控制的。有的服务端代码实现上存在一些问题,导致实际运行逻辑和session中的状态不一定匹配,从而产生一些逻辑漏洞。

步骤乱序

服务器在业务逻辑中需要校验之前的步骤有没有完成,如果没有做好检查,这样有些步骤可能被跳过,有些后面的步骤可以放在前面干扰业务逻辑,导致出现逻辑漏洞。
一个非常简单的例子就是在更换手机号的时候没有检查是否完成了旧手机号的验证,导致可以直接进行绑定新手机号的逻辑。

session 中字段名冲突

很多情况下一套业务逻辑是由多个步骤完成的,这时候在session中经常会存储一些值来记录业务流程中的一些数据。当提交的请求中不包含一些数据,但是业务逻辑的确又会用到这些数据的时候,这些数据有极大的可能存放在session中。程序员在开发的过程中为变量取名有一定的规律,比如为手机号码取名为phone,甚至在两个用于不同的业务逻辑中的手机号码习惯性的取同一个session名字,此时在session中发生字段名冲突,可能造成对应session值的覆盖。

以手机号码短信验证逻辑为例。在正确的业务流程中,每一个验证码有三个特征:phone(电话),code(验证码),type(业务)。一般分为四种类型:

  1. phone, code, type相互独立
  2. phone和code绑定
  3. type和code绑定
  4. 三者同时绑定

绑定的意思是,其中一项不能被单独覆盖掉。根据这四种类型,可以有如下几种攻击方式。

业务覆盖

用自己的修改密码处的验证码,提交在找回别人密码处。

用户名冲突

通过某些验证后,利用其他功能(如找回密码)将session中手机号替换成受害者的手机号。

验证码名冲突

验证码存放在session里,找其他能向任意手机发送验证码的地方,如注册处,获得的验证码填充在用于验证不可控的地方。

当然,正确的处理方式是phone, code, type三者绑定,并避免字段名冲突。

session和数据库不一致

为了方便,服务器经常会从session中取数据进行业务逻辑操作。而session作为数据库之上的缓存,可能会发生session与数据库不一致的情况。这种问题常常出现在在两个浏览器中登录同一个账号,在其中一个浏览器中对数据库进行了操作,导致数据库中的数据和第二个浏览器session中的数据不一致,可能会出现一些逻辑问题。

业务场景可能出现在物品买卖处,如果为了方便直接从session里获取余额而没查一次数据库,则可能出现问题。

最后,上述攻击模型不能覆盖到所有的实际场景,如有新的思路希望能一起探讨。

分享到 评论