openid 连接规范向授权端点添加了一个 nonce 参数,该参数必须作为 id_token 中的声明回显。它声称这个参数的目的是防止重放攻击,并且有一些关于使用 http only cookie 的实现建议。
我了解一般的重放攻击是什么,但我想更好地了解可以防止的重放攻击的详细信息,因此我可以更好地了解我是否有效地实施了它,或者犯了一些微妙的错误。
我假设重播攻击是针对授权端点的,以便某些第三方获取与不同用户相对应的令牌。是它还是别的什么?我们期望攻击者必须重播什么级别的信息?他们是否有用户代理和授权服务器之间的流量,但没有客户端应用程序,这就是为什么他们能够将流量重播到授权端点但不能将之前的 cookie 重播到客户端应用程序?或者他们有两者的浏览器历史但没有网络流量,所以他们没有旧的 cookie 值?用户代理是否还有以前的用户有关系吗?重放发生时与授权服务器的会话?如果前一个用户确实与授权服务器有一个有效的会话并且攻击者可以访问它,那么他们不能在不进行重放的情况下访问令牌吗?如果他们没有与授权服务器的有效会话,即使他们重放旧请求,用户也不会被提示?如果将提示用户进行身份验证,可能使用他们没有的凭据,那么重放的危险是什么?
我已经做了很多搜索,并且有一些类似的问题(Replay attack example for validating nonce? and Purpose of nonce validation in OpenID Connect implicit flow)实际上都没有回答有关这种特定重放攻击如何工作的问题。第一个只是从规范中引用了推荐的实现,然后谈到了泄露的令牌,这在我看来与重放攻击不同(如果攻击者有泄露的令牌,他们不是已经赢了吗?)。第二部分解释了重放攻击的一般概念,但没有讨论这种特定攻击的实际工作原理。
作为一些背景,我正在使用授权代码流制作一个 openid 连接应用程序(因此重播从 AS 到我的应用程序的重定向不应该做任何事情,因为您只能在 AFAICT 一次为令牌交换相同的授权代码,所以你会还需要重放授权端点以使重放攻击有意义。)我的应用程序正在使用我作为承载令牌返回的令牌来验证对我的 Web 服务器的请求,它们是整个会话状态,没有其他有意义的会话状态或本地管理的身份来绑定令牌。我的 openid 连接提供程序需要一个随机数,因为它是一种安全最佳实践。它在我的特定用例中真的有用吗?是我如此困惑的原因,因为实际上并没有为我的特定事物提供有意义的保护' 我在做什么?如果这确实对我有安全影响,我 110% 想确保我做正确的事,但我很难理解它保护我免受什么伤害。
由于不完全了解威胁向量,一些实现细节问题我很模糊:
- 我是否验证随机数与从令牌端点拉回后发送到授权端点的内容相匹配,然后假设它对会话有益?还是应该像检查签名一样,根据 nonce cookie 验证 id_token cookie 作为每个请求的一部分?
- nonce 应该与会话绑定,但术语 nonce 意味着它应该只使用一次。如果出于某种原因我需要通过授权端点将具有有效会话的用户发送回(获取一个新的 id_token 并在未来进一步到期?请求更广泛的范围?)我是否创建一个新的随机数?每次会话或每次调用授权一个随机数?