OAuth2.0 PKCE

0x00 背景

最近好好学习了一下OAUTH2.0,发现OAUTH2.0有很多认证方式,code flow和impicit flow大家都已经很熟悉了,我来总结一下使用pkce的code flow。
顺便,这个链接可以用来参考你该使用哪种flow:
https://auth0.com/docs/api-auth/which-oauth-flow-to-use

0x01 code flow with PKCE

PKCE模式适用于功能逻辑主要在客户端完成的native app。因为native app的custom scheme不像http的域名一样全剧唯一,所以即使auth server锁定了redirect的返回scheme,也不能保证跳转回正确的app。所以PKCE使用code_verifier和code_challenge来防止Authorization Code Interception Attack。这里主要考虑到的威胁是,native app必须经过浏览器才能进行redirect操作,在下图的第③步中,由于使用了app的custom schemer,如果有恶意app注册了同一个schemer,则不能保证第③步的重定向会回到你的app。
PKCE

0x02 其他flow的弱点

如果Resource Server的实现有问题会有下面这些问题:

  1. implicit flow
    a. 可能受到token replace攻击
    b. 可能受到csrf攻击
    c. 可能受到covert redirect 攻击
  2. code flow
    a. 可能受到csrf攻击
    b. 可能收到code泄露攻击{注意这里的code泄露攻击并不特指某种攻击方法,而是指在某些情况下(比如从服务器日志泄露、auth server没有限制redirect domain等等,当然这些情况并不能算是resource server的实现问题)泄露了code。由于code与state并不是一一对应的,所以即使你做了csrf防御,code泄露后也是可以被攻击者使用,攻击者使用他的state和泄露的受害者的code即可获得受害者的权限}
  3. code flow with pkce
    基本无懈可击。需要注意的是,pkce提供的是对Authorization Code Interception Attack的耐性,但是作为副作用,pkce也天然对csrf有耐性,在第③步中,即使是攻击者让受害者点击了含有攻击者code的app scheme,由于在受害者的app上并没有该与该code对应的code_verifier,所以第⑤步的请求发到auth sever也会被任为是无效请求,导致csrf失败。可以参考RFC:https://tools.ietf.org/id/draft-ietf-oauth-security-topics-12.html#rfc.section.3.1

另外,implicit flow和pkce都不需要client secret,所以不存在client secret泄露问题。

0x03 何为 covert redirect 攻击

covert redirect并不是指auth server的open redirect,而是指resource server自己有open redirect缺陷时会收到攻击。以下为具体例子:

http://auth_server/oauth?
  response_type=token&
  client_id=xyz&
  redirect_uri=http://real_resouce_server/redir_to=http://malicious/#token=AAA

这时由于redirect_uri的参数的域名为真正的resource server的域名,所以可以通过auth server的白名单进行跳转,但是问题是跳转到的是resource server的open redirect的endpoint,此时会进一步进行跳转,最终跳转到

http://malicious/#token=AAA

注意#后面的内容并不会直接发送的malicious服务器,但是通过javascript,是可以获取#后的内容并发送到malicious服务器的。

另一个问题是,code flow为何不受covert redirector影响?我们可以看一下同样情况下code flow的请求

http://auth_server/oauth?
  response_type=token&
  client_id=xyz&
  redirect_uri=http://real_resouce_server/redir_to=http://malicious/&code=AAA&state=BBB

客户端收到的响应为:

http://real_resouce_server/redir_to=http://malicious/&code=AAA&state=BBB

此时客户端的会如何跳转呢?答案是

http://malicious/

我们可以看到&符号后会被当作redir_to这个endpoint的参数来处理,并不会被认为是与http://malicious/一体的url。也就是说攻击者无法获得code。

0x04 参考

https://security.stackexchange.com/questions/175465/what-is-pkce-actually-protecting
https://www.atmarkit.co.jp/ait/articles/1710/24/news011.html
https://weblog.bulknews.net/covert-redirect-vulnerability-with-oauth-2-2c1f3083b1b4

前提是所有随机数生成算法没问题