话说前段时间 OAuth2.0 授权被人找出了个漏洞,各个开放平台都有影响,导致一阵恐慌。虽然后来发现其实是夸大其后果了,但也暴露出我们对这个经常用的协议仍一知半解的现状。所以花了点时间,整理了 OAuth1.0 和 2.0 的授权流程、以及其中的隐患和修复方案,供各位同学了解。由于本人也是临阵磨刀,难免疏漏,欢迎指点。

一、OAuth 1.0

a)OAuth1.0的授权流程为

caption id="attachment_1461" align="alignnone" width="600"] OAuth1.0授权流程(配图取自http://dev.t.qq.com/)[/caption

more其特点是请求request_token是需要传入app key和app secert, 而app secert是不能公开的, 因此只适合于服务器端授权。同时授权时的交互步骤比较多, 不够简便。

二、OAuth 2.0

a) OAuth2.0有两种授权方式

  1. Authorization code grant (Server Side),适合于有server端的应用授权
  2. Implicit grant(Client Side),适合于通过客户端访问的应用授权

b) Server Side的流程为

caption id="attachment_1463" align="alignnone" width="554"] OAuth2.0 Server Side授权流程(配图取自http://dev.t.qq.com/)[/caption

其中用户在打开的登录页, 登录授权之后得到的是授权码(code), 之后由用户把code填入第三方的应用, 应用的server获取到code的之后, 由server向oauth换取accesstoken, 之后可以把token保存在 server上。

其中授权回调时app server返回的state是用来在请求accesstoken时, 验证这个换token请求是不是同一个用户发起的,授权服务器会把state的值原样的返回给app server。

c) Client Side的流程为

caption id="attachment_1464" align="alignnone" width="593"] OAuth2.0 Client Side授权流程(配图取自http://dev.t.qq.com/)[/caption

其中,app直接把用户重定向到授权服务器登录, 用户登录之后app就能拿到token, 省却了跟app server的交互。但这里有个不太安全的地方, accesstoken是保存在客户端的, 有泄漏的风险。 由于oauth2。0已经放弃了使用app key和app secert来验证请求, 而app key是公开的。 因此只要攻击者拿到了用户的accesstoken, 就能调用api。

三、OAuth的XSRF攻击

a) OAuth 1.0

  1. 攻击者访问可靠的第三方站点(aaa.com), 在该网站发起OAuth认证流程, 保存包含request_token的授权URL1, 但不定向到该URL1所指的页面
  2. 把URL1中的oauth_callback参数改掉,换成攻击者自己的页面hack1,组成新的URL2,把该URL2发给受害者, 诱骗受害者点击
  3. 受害者点击URL2打开授权页, 发现是可靠的站点, 而不会发现有潜在的隐患, 因此会进行授权
  4. 受害者授权之后, 会回调到攻击者自己的页面hack1,攻击者就可以从这个页面获取到已授权的request_token和verifier,用这两个参数就能直接走到授权的第5步, 用request_token即可换取到access_token, 之后就可以使用access_token 访问受害者的数据(个人资料、私密文章之类的)了,如果这个网站(aaa.com)改密码的时候不用输入原密码,那么受害者的密码也会被改掉。

b) OAuth 2.0 (Server Side)

  1. 攻击者访问可靠的第三方站点(aaa.com), 且该网站提供了绑定帐号功能, 在该网站使用攻击者自己的帐号account1(aaa.com上的账号)发起OAuth认证和绑定流程(例如绑定qq账号), 之后用他自己的qq号qq1登录,然后保存包含code的重定向URL1, 但不定向到该URL1所指的页面
  2. 构造一个自动发起绑定请求的页面, 如创建一个img,src="url1"。 然后把该页面URL2发给受害者, 诱骗受害者点击
  3. 受害者点击URL2时, 如果恰好在 aaa.com (account2)登录了, 浏览器存有aaa.com的登录态, 这时就自动把受害者在aaa.com的帐号绑定到qq1上了
  4. 攻击者现在只要用qq1登录aaa.com, 就能访问到 受害者的数据(个人资料、私密文章之类的,甚至也能改密码)。

c) OAuth 2.0(Client Side)

Client Side的授权流程本身没有该问题, 不过由于Client Side是设计来给没有server的移动应用使用的, 其获取的access_token是保存在客户端的, 因此这里有泄漏的风险。

四、XSRF修复

  1. 可以要求OAuth1.0 的方式升级到 2.0, 由于1.0跟2.0的协议相差较大, 因此会有不少迁移特别是调试的工作;若保持使用OAuth1.0,则可以限制oauth_callback为固定url,不允许动态设置。
  2. 而OAuth 2.0 (Server Side)的方式, 可以要求app server必须对state进行验证, 从受害者发起的绑定请求, 由于他是中途进入的, app server上并没有保存相应的state, 这时server可以拒绝掉这次绑定请求。
  3. OAuth 2.0(Client Side)并没有这个问题, 可以不用修复。 重点在如何安全的保存access_token上。
Comments
Write a Comment
  • bsspirit reply

    此文写的很好!!确实存在上面问题。v1, 新浪微博的callback,会在server端设置的,如果客户端传参不是同一个callback地址会报错的。

Tags

css3   魅力CSS   nodejs   loading   CSS   疯狂的菊花   html5   animation   compiler   编译脚本   png   WordPress   智能   旅行   优化   模板   历史记录   跨域   manifest   frame   canvas   动画   js   离线应用   codelet   transform   抽取   java   兼容问题   发布脚本   富文本   那一年在他乡   htaccess   iframe   帧动画   加载速度   intelligent   跨浏览器   DNS解析   插件   checkbox   单边   step-start   vary   复选框   自动更新   转换   文本溢出   盒子阴影   menu   blob   西安   滑动背景   box-shadow   内存占用   键盘事件   python   auto   text overflow   background   所见所得   android   rotate   字节数   合并   文本框   slide   字符串连接符   协议   伪类   兄弟选择符   网格   节点位置比较   空白   斜线拼接   自定义命令   溢出   clock   素描   无法更新   分隔符   字符编码   body   下载文件   精灵图   step   nodej   ubuntu   apache   css3选择器   创建文件   多级菜单   编辑状态   ajax   阴影   垂直   chrome   管道   时钟   firefox   背景   文件上传   createobjecturl   游记   下载   放射渐变   版本号   宽高   照片   localStorage   渐变背景   图片   图片拼接   属性值检测   自动生成   计算   返回键   oauth   合图   reset   调用   cavnas   漏洞   按钮   margin   线性渐变   xsrf   被黑   tab   checked   修复   border   消失   step-end   sprite   common-upload   菜单   兄弟选择器   字符串   svn   九寨沟   缩进   css遮罩   svg   添加系统服务   gzip   插入代码   动态   加速   模拟