移花接木:针对OAuth2的攻击

作为第三方应用,为了提升用户体验,往往会提供第三方社交账号登录或者绑定的功能,这背后使用到的关键技术是OAuth认证。想要在自己的应用里集成OAuth不是难事儿,各大社交网站都提供了详尽的文档指南。

OAuth的复杂度比较高,有不少安全方面的坑,开发者在使用过程中一不注意可能就会掉进去,比如说不正确的使用OAuth2可能会遭遇到CSRF攻击。本文将对这个安全风险做一个通俗易懂的解释。 老司机发车前的特别提醒:阅读本文需要你对OAuth2有一些了解,可以参考文末的链接。

1. OAuth2 授权模式回顾

在开始之前,让我们先来回顾一下OAuth2中最典型的Authorization Code 授权模式,其大致流程如下:

图1:OAuth2 Authorization Code Flow

我们把OAuth2的整个认证过程大致分为三个阶段。第一阶段主要是向用户取得授权许可,对应图中的第1、2、3步;第二阶段主要是申请访问令牌(access_token),对应图中的第4、5步;第三阶段就是使用access_token获取用户数据。

这一过程中涉及了不少敏感参数和数据,例如client_secret相当于是第三方应用自己的密码,access_token某种程度上来讲就是用户的session id。由于这些参数以及数据极其特殊,我们当然得确保它们的安全性,HTTPS加密传输以及安全存储是必不可少的防护手段。不过仅仅做到这些是远远不够的,在这个流程里存在一个弱点,容易被攻击者利用进行CSRF攻击。

2. 针对OAuth2的CSRF攻击

2.1 攻击流程

让我们来看一个针对OAuth2的CSRF攻击的例子。假设有用户张三,和攻击者李四,还有一个第三方Web应用Tonr,它集成了第三方社交账号登录,并且允许用户将社交账号和Tonr中的账号进行绑定。此外还有一个OAuth2服务提供者Sparklr。

图2:模拟攻击案例中涉及的角色

Step 1. 攻击者李四登录Tonr网站,并且选择绑定自己的Sparklr账号。

Step 2. Tonr网站将李四重定向到Sparklr,由于他之前已经登录过Sparklr,所以Sparklr直接向他显示“是否授权Tonr访问”的页面。

Step 3. 李四在点击”同意授权“之后,截获Sparklr服务器返回的含有Authorization Code参数的HTTP响应。

Step 4. 李四精心构造一个Web页面,它会触发Tonr网站向Sparklr发起令牌申请的请求,而这个请求中的Authorization Code参数正是上一步截获到的code。

Step 5. 李四将这个Web页面放到互联网上,等待或者诱骗受害者张三来访问。

Step 6. 张三之前登录了Tonr网站,只是没有把自己的账号和其他社交账号绑定起来。在张三访问了李四准备的这个Web页面后,令牌申请流程在张三的浏览器里被顺利触发,Tonr网站从Sparklr那里获取到access_token,但是这个token以及通过它进一步获取到的用户信息却都是攻击者李四的。

Step 7. Tonr网站将李四的Sparklr账号同张三的Tonr账号关联绑定起来,从此以后,李四就可以用自己的Sparklr账号通过OAuth登录到张三在Tonr网站中的账号,堂而皇之的冒充张三的身份执行各种操作。

等等,这一切发生得太快,还没看清楚李四怎么就登录到张三的账号里去了。没关系,让我们从几个不同的角度来看看这当中发生了什么。

2.2 受害者张三(Resource Owner)视角

受害者张三访问了一个Web页面,然后,就没有然后了,他在Tonr网站上的账号就和攻击者李四在Sparklr上的账号绑定到了一起。伪造的请求是经过精心构造的,令牌申请这一过程在张三的浏览器里是非常隐蔽的被触发的,换句话讲就是,他根本不知道这背后发生了什么。

2.3 Tonr网站(Client)视角

从Tonr网站来看,它收到的所有请求看上去都是正常的。首先它收到了一个HTTP请求,其代表着当前用户张三在Sparklr网站上已经做了“同意授权”操作。其内容如下: