OAuth用户接管授权码

时间:2018-03-06 17:15:22

标签: oauth oauth-2.0 csrf

所以这个问题已经困扰了我一段时间了。请考虑以下情况:

背景:

  • 应用程序是与服务器(API)通信的SPA
  • 应用程序服务器(API)是无状态的。它不存储任何用户会话,只使用JWT令牌验证用户
  • 应用程序服务器具有/login端点,该端点可重定向到授权URL
  • 授权网址使用state端点生成的/login参数进行修饰
  • 调用/login端点会返回Set-Cookie标头,其中包含state值(在调用者'浏览器上设置Cookie)
  • 我们假设state值仅为userId

情景:

  1. 应用程序中有用户Tony
  2. Tony转到/login网址,将其重定向到授权网址
  3. Tony输入了他的凭据,但不知何故停止了重定向流程并获得授权coderedirect_urlstate查询参数,用户ID
  4. Tony发现在成功登录后,服务器对他的帐户执行了一些操作(dunno,只是一些东西)
  5. 现在的问题是:什么阻止Tony使用此数据向/callback端点发送请求(来自redirect_url的网址),但将用户ID从state param更改为某些其他用户ID并代表他做某事?

    我唯一想到的是...... Tony将如何知道另一个用户的身份。但是,如果它是公开的 - 那么我应该在这个例子中做些什么来防止这种情况呢?

    我希望我的榜样足够清楚。如果没有 - 请问,我会解释在我脑海里发生的事情:)

1 个答案:

答案 0 :(得分:1)

在通过http重定向将Tony发送到授权服务器之前,应用程序设置了state参数。它通过URL将状态参数值传递给授权服务器,例如authserver/authorize?state=tony...应用程序可以创建一个浏览器cookie来将状态值绑定到Tony的浏览器,或者在会话中以其他方式保存它。

现在,当Tony的拦截和修改后的回调网址发布到App,例如app/callback?code=abcd&state=bob...该请求可能来自Tony的浏览器或其他浏览器,但无论哪种方式,该应用都无法与浏览器会话中的bob匹配,因为该应用不会在此会话中设置并存储bob状态。

即使Tony将状态保留为tony但是从其他浏览器会话调用回调,该应用程序也无法匹配它,因此不会返回令牌。

另请注意,code只能使用一次。

此外,如果您可以控制应用程序服务器设置的state,您可以散列用户ID并使用base64ed散列作为state参数。这样你就无法猜出另一个有效状态。