为什么可以将授权代码流的状态参数存储在 cookie 中?

Why is it okay to store the state parameter for Authorization Code flow in a cookie?

在常规网络应用程序中实现授权代码流时,允许将状态参数存储在 cookie 中。参见 here and [here] (https://auth0.com/docs/protocols/oauth2/mitigate-csrf-attacks)

为什么将状态(又名随机数)存储在 cookie 中是一个可接受的解决方案?例如,如果我们在 nodejs 中执行此操作,代码将如下所示。

  app.use('/login', (_req, res) => {
    state = randomString(32)
    const authorizationEndpointUrl = new URL(`${activeConfig.authorization.domain}/authorize`);
    authorizationEndpointUrl.search = new URLSearchParams({
      audience: activeConfig.authorization.audience,
      response_type: 'code',
      redirect_uri: 'http://localhost:8443/callback',
      client_id: activeConfig.authorization.clientId,
      scope: activeConfig.authorization.scope,
      state,
    }).toString();
    res.cookie('state', state, { httpOnly: true }); // cookie set here
    res.redirect(authorizationEndpointUrl.toString());
  });

  app.use('/callback', req => {
     // check that url state matches req.cookie.state???
  })

但是如果我们这样做,是什么阻止了攻击者在响应 url 和 cookie 中设置相同的 "fake" 状态?我在这里错过了什么?

您用于跟踪状态的 cookie 不应该是可以伪造的。客户端至少应该对其进行签名,以便除了客户端本身之外没有人可以生成它。 届时,如果攻击者恰好在生成请求之后和返回合法响应之前有权访问设备,他们将只能重放此类 cookie,但不能伪造来自任意设备的自发授权响应。

根据您发布的链接,状态参数 (nonce) 应作为 url 参数添加到请求中。 oauth 将根据 url 参数而不是 cookie 进行验证。因此,将 nonce 存储在 cookie 中应该不是问题,它不是在 cookie 中寻找 nonce。攻击者不知道能够制作 url 参数的随机数,我认为这才是重点。存储随机数的位置并不重要。

令人困惑的是他们这样称呼 'state'。它专门针对 CSRF 攻击。不要与 oauth 令牌混淆。那些已经加密了。