1

首先感谢您的时间。我非常担心 Live Connect 的 OAuth2 API。

我遵循这一点,并使用 DotNetOpenAuth 为我们的联合身份和访问管理系统实施/集成 LiveId 身份验证/授权。

http://msdn.microsoft.com/en-us/library/live/hh243647.aspx#authcodegrant

在很长一段时间内一切正常。但是现在我在修复 LiveId 登录模块的重放攻击问题时遇到了严重的麻烦。让我们看一下上面文章中的授权码授予流程。

"*4. 用户代理使用重定向 URI 调用客户端,其中包括授权代码和客户端提供的任何本地状态。例如:...Callback.htm?code=AUTHORIZATION_CODE。 5. 客户端请求来自授权服务器的令牌端点的访问令牌,使用其客户端凭据进行身份验证,并包括在上一步中收到的授权代码。客户端包括用于获取授权代码以进行验证的重定向 URI。*"

在第 4 步之后,Live Connect OAuth2 服务器返回到我的回调端点,并带有授权码和状态,如下所示:

https://ssss.myapp.com:443/liveid/consume.idp?code=406dd558-0cda-50cc-bd37-d964ec29fbb3&state=uvygsnd3gba0jwi315kdyccs

问题是,授权码可以多次使用。因此它会导致严重的重放攻击问题,例如以下场景:

  1. 用户 A 在登录我的应用程序时,选择 LiveId 登录,然后他被重定向到 LiveId 登录页面。然后他登录,Live Connect OAuth2服务器返回回调端点,code=xxx&state=yyy...用户A然后使用此授权码获取访问令牌...

  2. 用户 B 在登录我的应用程序时,选择 LiveId 登录,然后他在 LiveId 的登录页面登录。Live Connect OAuth2 服务器现在返回 code=kkk&state=ggg

如果我这次,使用 Webscarab 之类的工具来捕获响应/请求,然后将 OAuth2 服务器的返回更改为 code=xxx&state=ggg(旧的授权码是给用户 A,而不是 B)。之后,使用此重放授权码请求访问令牌顺利进行。你猜怎么着?我再次收到了之前给用户 A 的 ACCESS TOKEN……最后,用户 B 可以作为用户 A 登录到我的应用程序。

请注意,对 Google OAuth2 服务器应用与上述相同的重放攻击,我收到来自服务器的错误请求错误,Google OAuth2 授权码永远不能被多次使用。并且代码流程或者确切地说,谷歌登录和 LiveId 登录的实现是完全一样的。

我使用 DotNetOpenAuth.OAuth2.WebServerClient 为 Google 和 LiveId 实现 OAuth2 身份验证流程。再次,完全相同的代码,但谷歌 OAuth2 服务器在重用授权代码时返回“错误请求”,但 LiveId 返回前一个用户的旧访问令牌。

这是一个严重的安全问题。希望大家对此有一些想法。或者希望我在某些方面是错误的。请指出。

非常感谢,Phuc Le。

4

1 回答 1

5

OAuth 2 规范在这里非常清楚

如果一个授权码被多次使用,授权服务器必须拒绝该请求并且应该(如果可能的话)撤销之前基于该授权码发布的所有令牌。

这是出于您上面提到的确切原因。

在您的情况下,您应该将此问题通知您的提供商

同时,您可以在客户端实现已使用授权码的缓存,并检查已发布的授权码。请注意,在提供者为两个不同的用户随机生成相同代码的情况下,这也可能产生误报(这可能不太可能,具体取决于实现)。

于 2013-06-17T20:12:32.910 回答