OAuth 2.0 定义了客户端在请求中发送的“状态”参数,以防止跨站点请求攻击。 OpenID 规范中也提到了“nonce”。除了在 ID 令牌而不是查询参数中返回“nonce”这一事实之外,它们似乎服务于完全相同的目的。如果有人能解释为什么他们是分开的
状态和随机数似乎相似。但是如果你深入挖掘,你会发现它们有不同的用途。
State 用于保护最终用户免受跨站请求伪造 (CSRF) 攻击。它是从 OAuth 2.0 协议 RFC6749 引入的。议定书指出,
一旦从最终用户获得授权,授权服务器将最终用户的用户代理重定向回客户端,并使用“state”参数中包含的所需绑定值。绑定值使客户端能够通过将绑定值与用户代理的身份验证状态匹配来验证请求的有效性
这用于授权请求。它使客户端能够验证授权响应未被更改并由原始服务器发送。请求已发送。简而言之,它允许客户端交叉检查授权请求和响应。
(详细说明:要接受授权码响应,客户端需要接受来自授权服务器的响应(例如:- 在 Web 应用程序中,这可以通过重定向和表单发布到后端来完成)。这意味着,我们的客户端应用程序有一个开放并接受请求的端点。状态参数通过将原始授权请求绑定到响应来保护此端点。这是 CSRF 保护。)
Nonce 有不同的用途。它将令牌与客户端绑定。它用作令牌验证参数,从 OpenID Connect specification 引入。
nonce - 用于将客户端会话与 ID 令牌相关联并缓解重放攻击的字符串值。该值未经修改地从身份验证请求传递到 ID 令牌。如果 ID 令牌中存在,客户端必须验证 nonce Claim Value 是否等于在 Authentication Request 中发送的 nonce 参数的值。如果存在于认证请求中,授权服务器必须在 ID 令牌中包含一个 nonce 声明,声明值是在认证请求中发送的 nonce 值。授权服务器应该不对使用的 nonce 值执行其他处理。 nonce 值是区分大小写的字符串
如您所见,nonce 值源自授权请求,由客户端生成。如果包含 nonce,它将出现在令牌中。因此客户端可以根据初始授权请求验证它收到的令牌,从而确保令牌的有效性。
此外,根据流类型,nonce 可以是强制参数。隐式流和混合流要求 nonce 值。这两个值都由客户端应用程序生成和验证。
为什么状态不能被重用?
如果捕获到授权请求,则恶意方可以伪造授权响应。这可以通过更改状态参数来避免。
Nonce 回答了浏览器的问题:这个 ID 令牌是对我最初请求的响应吗?
说明对后端服务器的回答:同意真的来自我认为的人吗?
所以他们回答类似的问题,但针对不同的实体。
state
用于浏览器,而 nonce
用于服务器。
我从他们的 RFC 中说明了一个解释。解释很简单。
状态
客户端用来维护请求和回调之间状态的不透明值。授权服务器在将用户代理重定向回客户端时包含此值。该参数应该用于防止跨站请求伪造
随机数
nonce 参数值需要包含每个会话的状态并且攻击者无法猜测。为 Web 服务器客户端实现此目的的一种方法是将加密随机值存储为 HttpOnly 会话 cookie,并使用该值的加密哈希作为 nonce 参数。在这种情况下,返回的 ID 令牌中的随机数与会话 cookie 的哈希值进行比较,以检测第三方的 ID 令牌重放。适用于 JavaScript 客户端的相关方法是将加密随机值存储在 HTML5 本地存储中,并使用该值的加密哈希。
参考链接:状态:https://datatracker.ietf.org/doc/html/rfc6749
随机数:https://openid.net/specs/openid-connect-core-1_0-17_orig.html
希望这能回答你的问题。
除了上述侧重于 state
和 nonce
安全方面的答案之外,如果您正在实施自己的三足 OAuth2 工作流程(客户端、中间件和联合身份提供程序,例如 Facebook),您的中间件可能有时需要一些上下文。例如,当 FIP 的响应在返回到客户端之前返回到您的中间件时,您可能需要了解更多有关原始请求的详细信息(即,对 FIP 的原始请求)。因为您的中间件很可能是无状态的,所以如果没有任何帮助,它将无法回答这个问题。这就是 OAuth2 state
变量的用武之地。您可以存储任何表示您希望在所有 OAuth2 跳转之间传递的状态的字符串,以便您的中间件(以及您的客户端)可以使用更多上下文。对于您的客户,这是出于安全原因使用的。出于纯粹的安全原因,nonce
被用作 OIDC 规范的一部分。
作为 MiiT 参与者,Mallory 以某种方式截获 ID 令牌并将令牌中继到依赖方(也称为受保护服务、资源服务器)。依赖方拒绝 ID 令牌,因为 Mallory 的浏览器中没有 session cookie。 nonce 和 session 的简化关系,nonce = hash(session, seed_rotated_regularly)
状态是依赖方在每个 HTTP 响应中生成的 CSRF token。作为用户,Alice 不小心点击了钓鱼链接,她的用户代理被重定向到身份验证服务(又名 OP,IdP)。由于单点登录,Alice 不会注意到来回的 HTTP 302。假设在 redirect_uri 中允许钓鱼网站。依赖方可以使用钓鱼网站获得的有效令牌拒绝 HTTP 请求,因为没有显示状态。 Nonce 在这种情况下不起作用,因为会话 cookie 在 Alice 的用户代理中。 State 无法阻止 MiiT,因为 Mallory 可以获取令牌、状态,但不能获取会话 cookie。
实际上“NONCE”足以验证发送者和响应。但在您打开令牌之前应该阅读“NONCE”。因此,如果有数百万个虚假响应,您必须接受响应,您将接受所有这些以打开令牌并阅读“NONCE”。但是状态已经在响应头上打开,您可以轻松读取状态并轻松拒绝虚假响应。这是两级检查。
为了演示差异,让我们考虑一种情况,其中 state
存在但 nonce
不存在,并且攻击者能够拦截身份验证响应(从授权服务器或 OIDC 提供程序重定向到客户端)并注入恶意授权代码具有相同的 state
参数。这更可能发生在原生应用程序中,可以通过使用 nonce
参数方法来缓解。
或者攻击者可以很容易地使用在攻击者的客户端应用程序上截获的授权码来登录受害者的帐户。 (如果存在 nonce
,也可能发生这种情况,因为攻击者可以更改客户端应用程序以绕过 nonce
检查。授权服务器或 OIDC 提供者应通过检测相同授权代码的多次使用或给予完全相同的同意来防止这种情况短时间内)
PKCE 也可以用作一种复杂的方法,但是所有的授权服务器或 OIDC 提供者可能不支持它。
不定期副业成功案例分享