最近收到了一份安全漏洞警告--用户账户恶意劫持漏洞,直指我们联登中的state参数存在严重问题
在之前的《常识二Oauth2.0介绍及安全防范》文章中已经说明了oauth2.0以及可能的csrf问题
看来知道和做到还是有些差距,通过这篇文章再来回顾一下此次漏洞问题
相关知识点
详细的说明可查看:《常识二Oauth2.0介绍及安全防范》,这儿作个简单回顾
CSRF
CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSRF/XSRF
oauth2.0
由于oauth2.0的交互需要好几步,所以存在跨域攻击风险
state参数
oauth2.0的提供者定义接口时,都会有一个非必选state参数
state 用于保持请求和回调的状态,授权请求成功后原样带回给第三方。该参数用于防止csrf攻击(跨站请求伪造攻击),强烈建议第三方带上该参数。参数设置建议为简单随机数+session的方式
想要防范风险,state参数值需要具备下面几个特性:
- 不可预测性:足够的随机,使得攻击者难以猜到正确的参数值
- 关联性:state参数值和当前用户会话(user session)是相互关联的
- 唯一性:每个用户,甚至每次请求生成的state参数值都是唯一的
- 时效性:state参数一旦被使用则立即失效
漏洞详情
其实我们的接口中,是有state参数的,那么为什么会有漏洞呢?
使用第三方联登,不会简单的登陆上就可以了,还需要把联登帐户绑定到正常帐户(已经有了就直接绑定,没有就注册一个新帐户)上,这应该是通用的用法了,第三方联登只是作为一种引流。
所以攻击者一般把自己的第三方帐户与受害者绑定,就可以达到窃取受害者帐户的目的
state参数的作用,只是防止了非本应用发出的认证url
张三怎么能用李四的code呢?作为oauth provider是没法知晓的,只能client通过state判别,是不是由合法client发出的
但,如果client把state给泄漏了呢?
这就是我们这次的漏洞场景之一:之前有个‘分享帐户’的功能,其实就是在个人中心中绑定自己的第三方帐户
如果攻击者在这儿把自己的authorize url给了受害者,这个url中带了合法的state参数,那这个url就是合法的,应用本身成了攻击者的帮凶。
那么对于这种情况如何防范呢?
最根本原因是我们的state参数:关联性:state参数值和当前用户会话(user session)是相互关联的,没有完美实现
一个用户的state不能给别的用户使用
用户登陆了可以使用userid与state关联
用户未登陆,可以使用用户设备号与state关联,识别url与state的关系
这样就能防范一切情况
结语
安全与监控实在是太重要了,从开发者角度讲,这个功能已经上线很久,功能正常。但从安全角度来讲,实则完全不能上线。
各个功能点,不管是开发,还是产品都可能会忽略了单个功能产生的交叉漏洞,这需要安全去监测,监控。
近期上线了个功能,功能一切正常,但在监控时发现在线上会有严重的性能问题;如果不是监控,可能这个问题会在下次搞活动时才会被发现,造成严重问题!