针对 OAuth2.0 的 CSRF 攻击

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了针对 OAuth2.0 的 CSRF 攻击相关的知识,希望对你有一定的参考价值。

参考技术A

这篇文章的主要内容来源于另外一个作者,文章地址: 移花接木:针对OAuth2的CSRF攻击
不过针对 OAuth2.0 的 CSRF 攻击我有两个疑问点,先列出来:
1.如果授权码(Authorization code)和 client_id、redirect_uri 是绑定的,即便攻击者把 Tonr 网站触发申请令牌的 HTTP 请求中的授权码替换了,Sparklr 认证服务器校验 code 的合法性时发现其对应的 client_id 等不一致,那么这个code会被认定为不合法的,攻击就会失败

2.有人会说获取授权码(Authorization code)的 HTTP 请求是 GET 方式,截获 client_id、redirect_uri 很容易,然后在 Tonr 网站申请令牌的 HTTP 请求中 client_id、redirect_uri 把也都替换掉,那这样的话,获取的 token 就不再是属于张三的了,攻击也会失败

下面是原文章内容

为了提升用户的帐号登录、注册体验,往往会在我们的 Web 网站、App 中提供如 QQ、WeChat、Sina等第三方社交帐号登录或者绑定的功能,通过上一篇文章 理解OAuth2.0 我们知道这背后使用到的关键技术是 OAuth2.0 认证,想要在自己的 Web 站点、App 中集成第三方帐号登录不是难事,第三方服务提供者都有详细的文档指南

这篇文章我们聚焦关注下 OAuth 安全方面的坑,被人经常谈起的一个 OAuth 安全问题就是开发者不规范化使用 state 而引起的 CSRF 攻击

我们看一个针对 OAuth2.0 的 CSRF 攻击的例子。假设有用户张三、攻击者李四,第三方应用 Tonr(该应用集成了第三方社交账号登录,并且允许用户将社交帐号和 Tonr 中的帐号进行绑定),以及 OAuth2.0 服务提供者 Sparklr

1 攻击者李四登录 Tonr 网站,使用 Sparklr 帐号授权登录 Tonr 网站,并且将 Sparklr 帐号与 Tonr 网站的帐号进行绑定
2 李四选择使用 Sparklr 帐号授权登录 Tonr 网站,根据 OAuth2.0 授权登录流程,此时 Tonr 网站会将李四的请求导向 Sparklr 的认证服务器,询问是否同意授权 Tonr 网站
3 李四在点击 同意授权 之后,截获 Sparklr 认证服务器返回的 code 参数
4 李四精心构造一个 Web 页面,它会触发 Tonr 网站向 Sparklr 发起申请令牌的请求,而这个请求中的 code 就是上一步截获的 code
5 李四将这个 Web 页面放到互联网上,等待或诱骗受害者张三来访问
6 张三之前登录过 Tonr 网站,只是没有把自己的帐号与其他社交帐号绑定起来。在张三访问李四准备的这个 Web 页面的时候,触发了令牌申请流程,Tonr 网站从 Sparklr 那里获取到 Access token ,但是这个 token 以及通过它进一步获取到的用户信息都是攻击者李四的
7 Tonr 网站将李四的 Sparklr 帐号同张三的 Tonr 帐号关联绑定起来,从此以后,李四就可以用自己的 Sparklr 帐号通过 OAuth 授权登录到张三在 Tonr 网站中的帐号,堂而皇之的冒充张三的身份执行各种操作

我们从不同的角度看看这其中发生了什么?

受害者张三访问了一个 Web 页面,然后就没有然后了,他在 Tonr 网站上的帐号就和攻击者李四在 Sparklr 上的帐号绑定在一起了。他根本不知道发生了什么

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

当 Tonr 网站收到这样的请求时,它以为用户张三已经同意授权,于是就发起后续的令牌申请请求,(注意此时申请令牌的请求中的 code 已经被替换成攻击者李四的 code ),用收到的 Authorization code 向 Sparklr 网站换取 Access token ,只不过最后拿到的是攻击者李四的 Access token

最后,通过 Access Token 换取到用户张三在 Tonr 网站的帐号信息并与攻击者李四在 Sparklr 网站的帐号进行绑定

对于 Sparklr 网站来说,只要收到的参数是正确的有效的,那就提供正常的认证服务,仅此而已

在用户张三同意 Sparklr 授权 Tonr 网站的授权请求后,攻击者将 Sparklr 网站返回的授权码(Authorization code) 替换成自己提前获取到的 code 。这样,当受害者访问到攻击者精心准备的 Web 页面并向 Sparklr 发起申请 Access Token 令牌的 HTTP 请求,实际上是在用张三在 Tonr 网站上的帐号和李四在 Sparklr 网站上的帐号进行绑定

攻击完成之后,李四在 Tonr 网站上可以使用自己在 Sparklr 网站上的帐号进行登录,而且登录进去的是张三在 Tonr 网站上的帐号,同理张三通过自己在 Tonr 网站上的帐号登录进去之后,看到的是李四在
Sparklr 网站上的数据

从整体上来看,这次攻击的时序图应该是下面这个样子:

要想完成 CSRF 攻击也是不容易进行的
首选,用户张三必须在 Tonr 网站已经拥有了一个个人帐号

其次,整个攻击必须要在短时间内完成,因为第三方服务提供商的认证服务器颁发的授权码(Authorization code) 有效期很短,OAuth2.0 官方建议控制在 10分钟 ,一旦 Authorization code 过期后那么后续的攻击也就不能进行下去了

最后,一个 Authorization code 只能被使用一次,如果第三方服务提供商收到重复的 Authorization code ,它会拒绝当前令牌的申请请求。不仅如此,根据 OAuth2.0 官方推荐,它还可以把和这个已经使用过的 Authorization code 相关联的 Access Token 全部撤销掉,进一步降低安全风险

要防止这样的攻击也不难,作为第三方应用的开发者,只需要在 OAuth 认证过程中加入 state 参数,并验证它的参数值即可,具体细节如下:

state 参数在 OAuth2 认证过程中不是必选参数,因此第三方应用开发者在集成 OAuth2 认证的时候,容易忽略该参数的存在,导致容易受到 CSRF 攻击。并且,这种攻击比较巧妙,可以悄无声息的攻陷受害者的帐号,难以被察觉

所以,作为第三方应用开发者,我们只需要在 OAuth2.0 认证过程中明确提供 state 参数并验证其参数值,即可防御这样的攻击

保护 oauth 不记名令牌免受 javascript 应用程序中的 XSS、CSRF 等攻击

【中文标题】保护 oauth 不记名令牌免受 javascript 应用程序中的 XSS、CSRF 等攻击【英文标题】:Securing oauth bearer token against attacks such as XSS, CSRF in javascript apps 【发布时间】:2014-08-13 07:07:12 【问题描述】:

我有点不清楚在使用纯 JavaScript 应用程序时如何保护(或保护)不记名令牌。

我知道当用户向服务器请求令牌时,它的有效期可能为 14 天或 24 小时。但是一旦用户拥有令牌,就没有简洁(可靠)的方法来保护它免受 XSS 或 CSRF 攻击(我错过了什么吗?)。

现在假设用户已登录到 Web 应用程序,并且浏览器拥有此令牌,有效期为 14 天。如果用户正在访问另一个尝试执行 XSS(或 CSRF)的 Web 应用程序,则令牌会暴露给第三方应用程序,并且此应用程序可以使用此令牌调用我的应用程序(?)

我尝试在线搜索,但没有具体的(或易于理解的)纯 js 应用程序以及如何保护令牌。或者在 js atm 中没有好的方法可以做到这一点。你只是希望(并祈祷)攻击不会在令牌的有效期内发生(即 14 天:|)?

欢迎对此提出任何想法或意见。

谢谢

编辑:它可能。不用说,但我们假设使用 SSL 证书。

【问题讨论】:

我认为您需要了解什么是 CSRF 和 XSS 攻击,然后再开始尝试保护您的应用程序免受它们的攻击。 【参考方案1】:

所以,一个非常快速的总结。发生 CSRF 是因为对 HTTP 端点的请求会自动包含 cookie(应该如此)以及服务器描述的所需标头,并且不需要用户进行物理操作。他们只需访问一个带有 CSRF 矢量的网页。

如果没有使用首先传递给客户端并返回到服务器以验证用户确实打算拨打电话的唯一“秘密”,则通常认为 CSRF 是可能的。一般来说,Web 浏览器正在塑造保护任何类型应用程序免受 CSRF 攻击的主要方法。 CSRF on OWASP

正如您所指出的,您使用不记名令牌(作为 HTTP 标头发送) - 但您仍然受到保护,因为默认情况下请求需要来自同一来源。如果服务器允许来自所有来源的调用,这些调用在 HTTP 标头中返回(它会告诉您用户的 Web 浏览器是否允许),那么在他们的头上就是 Same origin policy here。

至于 XSS,只要您的 cookie 至少具有“HTTP”标志,它们对用户访问的任何页面上的 javascript 代码都是不可见的。加上严格意义上的 XSS 向量,包括窃取您网站的 cookie,一般来说需要在您的网站上执行。无论如何,除非用户在您的网站上,否则我无法想到要窃取它们。如果您设置“安全”标志,这会更好,因为它也仅强制“服务器”,并确保仅在建立 TLS/SSL 连接时发送 cookie。 XSS on OWASP

以下是列出带有安全和 HTTP 标志的 cookie 的屏幕截图:

另外,请确保始终强制执行 TLS 连接,否则它们可能会成为对公共 WIFI 网络的 MITM(中间人)攻击的受害者,该攻击会强制协议降级为易受攻击的 SSL 的弱版本贵宾犬或根本没有。请阅读 HSTS,因为它肯定会加强我提到的所有内容,并真正有助于防止令牌被盗 HSTS OWASP 和 HSTS info wikipedia

【讨论】:

以上是关于针对 OAuth2.0 的 CSRF 攻击的主要内容,如果未能解决你的问题,请参考以下文章

防止CSRF攻击与针对CSRF方法接口测试的调整

案例解析一次针对XSS+CSRF构造蠕虫的渗透测试

如何解决CSRF 攻击

IT新手之路关于oauth2.0的简单理解

CSRF 攻击的应对之道 -- 转

剖析使用CSRF攻击实现银行转账原理