FB Oauth CSRF 安全,PHP 网站

信息安全 csrf oauth2
2021-08-28 14:41:56

我正在尝试使用 Twitter 和 Facebook 进行第三方登录。

从这些方获取访问令牌并确认其有效性后,我会发布自己的 JWT 令牌,该令牌在我的应用程序集群中使用。我使用第 3 方令牌的唯一目的是获取电子邮件地址和用户 ID,我不会以任何其他方式与社交网络交互,除非重新验证。基本上它只是为了让用户不必填写新密码。

我有几个服务,每个服务都在不同的子域上。这些服务在某种程度上遵循了微服务的理念,并且各自负责狭窄范围的功能(例如 UAC、业务实体 repo 等)

JWT 令牌的唯一目的是降低其他服务之间的身份验证检查复杂性,这不应该是 Oauth 提供者知道的。我也不想确定他们在公开可见的 JWT 中选择了哪个提供商。

我在 UAC 微服务上安装了第三方(官方批准的)SDK,我通过 AJAX 请求与之交互。

编辑:更新流程,更清晰

  1. 从表示层:需要来自 UAC 模块的授权 URL。在 UAC 模块方面,SDK 处理 CSRF 令牌的创建和存储(至少 FB SDK 是这样)。CSRF 令牌被设置到会话中。
  2. 将用户重定向到 FB auth 页面,用户授权,使用 CSRF 令牌发送回我的表示层以进行比较
  3. 这是 CSRF 检查应该发生的地方,但原始令牌未在当前会话中设置,而是在 UAC 模块中
  4. 从表现层 - 服务器端:获取 Oauth 令牌和 CSRF 令牌,将其发送到 UAC 模块
  5. 这是 CSRF 检查可能发生的地方,但服务器-服务器通信没有会话。这是我通过欺骗 SDK 接受刚刚进入的任何 CSRF 令牌来跳过 CSRF 检查的地方
  6. 验证 Oauth 令牌,交换长期令牌,获取用户数据,在我的数据库中创建用户实体,发出 JWT,完成。
  7. JWT 是从表示层设置的 - 使用 SetCookie 的服务器端。这个 cookie 使用 HttpOnly 和 Secure (但这不是真正的问题)

简单来说:我想通过这些提供程序实现与常规 Oauth 相同的功能,但我需要在两个子域之间拆分流程。如果可能的话,这些都不应该有一个 PHP 会话,除了 FB SDK 迫使我使用一个的短暂时刻。

到目前为止我所尝试的:我稍微改变了架构,而不是直接从 javascript 与 UAC 模块对话,而是通过表示层的服务器端反弹请求,并在该会话中存储原始 CSRF令牌。当用户稍后从 FB auth 页面返回时,我可以执行检查。我仍然必须在 UAC 端欺骗 SDK,但那是在我验证了 CSRF 之后(尽管不是通过 SDK 本身)我可以继续使用这种方法吗?这是否有风险,因为我在服务器之间发送 CSRF 令牌?

1个回答

它不完全清楚这里的实际问题是什么,但它似乎与 CSRF 有关,我将回答这个问题,假设它与如何最好地防止 CSRF 有关。

我建议在严格模式 [1][2] 下实现 cookie 属性“sameSite”。

SameSite 是一个“较新”的 cookie 属性,主要用于防止 CSRF 样式攻击。将值设置为“STRICT”可确保所有 HTTP 方法都受到保护,即,如果将值设置为“LAX”,则 GET 请求将发送 cookie,而“POST”请求则不会等。建议使用“LAX”是一种平衡,但这有点主观,需要上下文。设置为“STRICT”可确保浏览器永远不会发送来自来源以外的 cookie。

[1] MDN Cookie 属性: https ://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies

[2] OWASP sameSite https://www.owasp.org/index.php/SameSite