OAuth 2.0定义了客户端在请求中发送的“状态”参数,以防止跨站点请求攻击。在 OpenID 规范中也提到了“ nonce”。除了“ nonce”在 ID 标记中而不是查询参数中返回外,它们似乎还有完全相同的用途。如果有人能解释为什么他们是分开的
国家和现在似乎是相似的。但如果你深入挖掘,你会发现他们服务于不同的目的。
状态 是用来保护最终用户免受跨站点请求伪造(CSRF)攻击的。它是从 OAuth 2.0协议 RFC6749中引入的。协议规定,
一旦从最终用户获得了授权,则 授权服务器将最终用户的用户代理重定向回 包含所需绑定值的客户端 parameter. The binding value enables the client to verify the 通过将绑定值与 用户代理的身份验证状态
这是在授权请求中使用的。它使客户端能够验证授权响应没有被更改,并且由授权的原始服务器发送。请求已经发出。简而言之,它允许客户机交叉检查授权请求和响应。
(更详细说明: 要接受授权代码响应,客户端需要接受来自授权服务器的响应(例如:-在 Web 应用程序中,这可以通过重定向和表单发送到后端来完成)。这意味着,我们的客户端应用程序具有一个打开的端点并接受请求。状态参数通过将原始授权请求绑定到响应来保护此端点。这是 CSRF 保护。)
Nonce 服务于不同的目的。它将令牌与客户端绑定在一起。它作为令牌验证参数,是从 OpenID 连接规范引入的。
Nonce -字符串值,用于将 Client 会话与 ID 令牌相关联,并减轻重播攻击。该值通过未修改的方式从身份验证请求传递到 ID 令牌。如果出现在 ID 令牌中,客户端必须验证 nonce 索赔值是否等于身份验证请求中发送的 nonce 参数的值。如果出现在身份验证请求中,授权服务器必须在 ID 令牌中包含一个临时索赔,索赔值是在身份验证请求中发送的临时值。授权服务器不应该对使用的临时值执行其他处理。Nonce 值是区分大小写的字符串
如您所见,nonce 值来自授权请求,由客户机生成。如果包含 nonce,则它将出现在令牌中。因此,客户机可以根据初始授权请求验证它收到的令牌,从而确保令牌的有效性。
此外,根据流类型的不同,马上可以是一个强制参数。隐式流和混合流要求 马上值。在客户端应用程序中,这两个值都是 产生和 有效。
为什么国家不能被重用?
如果捕获了授权请求,那么恶意方可以伪造授权响应。这可以通过改变状态参数来避免。
I am stating an explanation from their RFCs. The explanation is pretty straightforward.
国务院
客户端用于维护请求和回调之间的状态的不透明值。授权服务器在将用户代理重定向回客户端时包含此值。这个参数应该用来防止 跨站请求伪造
Nonce
Nonce 参数值需要包含每个会话状态,并且攻击者无法猜测。为 Web 服务器客户端实现这一点的一种方法是将加密随机值存储为 HttpOnly 会话 cookie,并使用该值的加密散列作为 nonce 参数。在这种情况下,将返回的 ID 令牌中的 nonce 与会话 cookie 的散列进行比较,以检测第三方的 ID 令牌重播。适用于 JavaScript 客户端的一个相关方法是将加密随机值存储在 HTML5本地存储中,并使用该值的加密散列。
参考链接: State: https://datatracker.ietf.org/doc/html/rfc6749
Nonce:https://openid.net/specs/openid-connect-core-1_0-17_orig.html
希望这能回答你的问题。
Nonce 向浏览器回答这个问题: 这个 ID 令牌是对我最初请求的响应吗?
对后端服务器的状态回答: 这个同意真的来自于我认为它来自的人吗?
因此,他们回答类似的问题,但不同的实体。
除了上述关注于 state和 nonce的安全方面的答案之外,如果你正在实现你自己的三条腿的 OAuth2工作流(客户端、你的中间件和联邦身份提供商,比如 Facebook) ,你的中间件有时可能需要一些上下文。例如,当来自 FIP 的响应在返回到客户端之前回到您的中间件时,您可能需要更多地了解原始请求(即,对 FIP 的原始请求)的细节。因为您的中间件很可能是无状态的,所以如果没有任何帮助,它将无法回答这个问题。这就是 OAuth2 state变量发挥作用的地方。您可以存储任何字符串,这些字符串表示您希望在所有 OAuth2跳转之间传递的状态,以便您的中间件(以及您的客户机)可以使用更多的上下文。对于您的客户端,这是出于安全原因使用的。出于纯粹的安全原因,nonce被用作 OIDC 规范的一部分。
state
nonce
作为 MiiT 参与者,Mallory 以某种方式拦截 ID 令牌,并将令牌转发给信赖方(也就是受保护的服务、资源服务器)。依赖方拒绝 ID 令牌,因为 Mallory 的浏览器中没有 会话 cookie。Nonce 与 session,Nonce = hash (会话,育种 _ 旋转 _ 定期)之间的简化关系
状态是依赖方在每个 HTTP 响应中生成的 CSRF 令牌。作为用户,Alice 偶然单击钓鱼链接,她的用户代理被重定向到身份验证服务(又名 OP,IdP)。由于单点登录,Alice 不会注意到来回的 HTTP 302。假设 redirect _ uri 中允许钓鱼网站。依赖方可以用钓鱼网站获得的有效令牌拒绝 HTTP 请求,因为没有显示状态。Nonce 在这种情况下不起作用,因为会话 cookie 在 Alice 的用户代理中。State 不能阻止 MiiT,因为 Mallory 可以获得标记、状态,但不能获得会话 cookie。
实际上“ NONCE”足以验证发件人和响应。 但在打开令牌读取“ NONCE”之前。 因此你必须接受回应 如果有数以百万计的虚假回复,你将接受所有这些打开令牌并读取“ NONCE”。 但是 国家已经在响应头上打开了,您可以很容易地读取状态并且很容易地拒绝虚假响应。 这是两级检查。
为了演示这种差异,让我们考虑这样一种情况: state存在,但是 nonce不存在,而且攻击者能够拦截身份验证响应(从 Authorization Server 或 OIDC Provider 重定向到客户端) ,并注入具有相同 state参数的恶意授权代码。这种情况更可能发生在本地应用程序中,可以通过使用 nonce参数方法来减轻这种情况。
或者,攻击者可以轻松地使用在攻击者的客户端应用程序上截获的授权代码登录到受害者的帐户。(如果存在 nonce,也会发生这种情况,因为攻击者可以改变客户端应用程序以绕过 nonce检查。授权服务器或 OIDC 提供程序应该通过检测同一授权代码的多个用法或在短时间内给予完全相同的同意来防止这种情况的发生)
PKCE can also be used as a sophisticated method, but all of the authorization servers or OIDC Providers may not support it.