当 OAuth 用户接管授权码时
When OAuth user takes over the authorisation code
这个问题已经困扰我一段时间了。考虑这种情况:
背景:
- 应用程序是与服务器通信的 SPA (API)
- 应用程序服务器 (API) 是无状态的。它不存储任何用户 session,仅使用 JWT 令牌对用户进行身份验证
- 应用程序服务器有一个
/login
端点重定向到授权 url
- 授权 url 用
state
参数修饰,该参数在 /login
端点 中生成
- 使用
state
值调用 /login
端点 returns a Set-Cookie
header(在调用者的浏览器上设置 cookie)
- 假设
state
值只是一个 userId
场景:
- 应用中有一个用户Tony
- Tony 转到
/login
url,这将他重定向到授权 url
- Tony 输入了他的凭据,但不知何故停止了重定向流程并获得了授权
code
、redirect_url
和具有用户 ID 的 state
查询参数
- Tony 发现在成功登录后服务器对他的帐户做了一些操作(不知道,只是一些东西)
现在的问题是:是什么阻止 Tony 使用此数据将请求发送到 /callback
端点(url 来自 redirect_url
)但更改用户 ID 来自 state
参数给其他用户 ID 并代表他做一些事情?
我唯一想到的是...Tony 怎么会知道另一个用户的 ID。但是如果它是公开可用的——那么在这个例子中我应该怎么做才能防止这种情况?
希望我的示例足够清楚。如果不是-请问,我会解释我的想法:)
状态参数由应用程序在通过 http 重定向将 Tony 发送到授权服务器之前设置。它通过 URL 将状态参数值传递给授权服务器,例如authserver/authorize?state=tony...
应用程序可能会创建浏览器 cookie 以将状态值绑定到 Tony 的浏览器或以其他方式在会话中保存它。
现在,当 Tony 的拦截和修改回调 URL 发布到应用程序时,例如app/callback?code=abcd&state=bob...
请求可能来自 Tony 的浏览器,或完全来自其他浏览器,但无论哪种方式,应用程序都无法在浏览器会话中匹配 bob
,因为应用程序未设置和存储此会话中 bob
的状态。
即使 Tony 离开 tony
状态但从不同的浏览器会话调用回调,应用程序也无法匹配它,因此不会 return 令牌。
另请注意,code
只能使用一次。
此外,如果您可以控制应用程序服务器设置的内容 state
,您可以散列用户 ID 并将 base64ed 散列用作 state
参数。这样你就无法真正猜出另一个有效状态。
这个问题已经困扰我一段时间了。考虑这种情况:
背景:
- 应用程序是与服务器通信的 SPA (API)
- 应用程序服务器 (API) 是无状态的。它不存储任何用户 session,仅使用 JWT 令牌对用户进行身份验证
- 应用程序服务器有一个
/login
端点重定向到授权 url - 授权 url 用
state
参数修饰,该参数在/login
端点 中生成
- 使用
state
值调用/login
端点 returns aSet-Cookie
header(在调用者的浏览器上设置 cookie) - 假设
state
值只是一个userId
场景:
- 应用中有一个用户Tony
- Tony 转到
/login
url,这将他重定向到授权 url - Tony 输入了他的凭据,但不知何故停止了重定向流程并获得了授权
code
、redirect_url
和具有用户 ID 的 - Tony 发现在成功登录后服务器对他的帐户做了一些操作(不知道,只是一些东西)
state
查询参数
现在的问题是:是什么阻止 Tony 使用此数据将请求发送到 /callback
端点(url 来自 redirect_url
)但更改用户 ID 来自 state
参数给其他用户 ID 并代表他做一些事情?
我唯一想到的是...Tony 怎么会知道另一个用户的 ID。但是如果它是公开可用的——那么在这个例子中我应该怎么做才能防止这种情况?
希望我的示例足够清楚。如果不是-请问,我会解释我的想法:)
状态参数由应用程序在通过 http 重定向将 Tony 发送到授权服务器之前设置。它通过 URL 将状态参数值传递给授权服务器,例如authserver/authorize?state=tony...
应用程序可能会创建浏览器 cookie 以将状态值绑定到 Tony 的浏览器或以其他方式在会话中保存它。
现在,当 Tony 的拦截和修改回调 URL 发布到应用程序时,例如app/callback?code=abcd&state=bob...
请求可能来自 Tony 的浏览器,或完全来自其他浏览器,但无论哪种方式,应用程序都无法在浏览器会话中匹配 bob
,因为应用程序未设置和存储此会话中 bob
的状态。
即使 Tony 离开 tony
状态但从不同的浏览器会话调用回调,应用程序也无法匹配它,因此不会 return 令牌。
另请注意,code
只能使用一次。
此外,如果您可以控制应用程序服务器设置的内容 state
,您可以散列用户 ID 并将 base64ed 散列用作 state
参数。这样你就无法真正猜出另一个有效状态。