微服务架构中的 CSRF

信息安全 csrf 建筑学 弹簧框架
2021-08-26 03:36:03

在微服务架构中实现 CSRF 保护的正确方法应该是什么?服务是无状态的。

  1. 将CSRF验证放在系统入口上?例如网关

    使用此选项,我无法保证客户网关会执行此操作。

  2. 还是在每个微服务上?

    在这里,我们可以保证服务将按照某些规范构建。 问题是服务到服务的通信。在这种情况下,服务是否需要将 CSRF 令牌传递给另一个服务或某些标头 API 密钥?因为有些服务可以从网关访问,也可以直接从另一个服务访问。

2个回答

TL;DR:在您处理身份验证的同一位置(网关或它后面的服务)处理 CSRF。或者不要将 cookie 用于身份验证令牌。

长版

在无状态设计中,最常见的 CSRF 保护方法是双重提交 cookie即使服务器没有状态或会话,客户端也存在安全会话。以一种与此安全会话相关联的方式实现双重提交 cookie 并且不要天真地执行它,这一点非常重要。有关详细信息,请参阅本文。

实现此目的的一种方法是将 CSRF 令牌包含在身份验证 cookie 中,并使身份验证 cookie 为 httpOnly。这样,受感染子域的攻击者将被迫覆盖身份验证 cookie 和 CSRF 令牌,这是他无法做到的,因为他无法伪造身份验证 cookie。即使他有一个有效的身份验证 cookie(例如他自己的),这也会改变经过身份验证的用户,从而首先破坏 CSRF 的目的。此外,覆盖 cookie 并不足以击败 CSRF,因为客户端应用程序没有从 cookie 本身读取 CSRF 令牌(它是 httpOnly),但在成功验证时会获得一个 CSRF 令牌。

可以在此处找到实施此方法所需的步骤。即使该链接上的答案是关于 JWT,同样的方法也适用于您用于身份验证的任何令牌格式。

在无状态微服务架构中,最好的方法是在处理身份验证的同一位置处理 CSRF,无论是在网关上还是在其后面的其他服务上,因为您需要处理每个请求的身份验证并且 CSRF 令牌是(如果您实施我的建议以上)绑定到身份验证。任何其他选项都会使事情进一步复杂化,并可能完全破坏 CSRF 保护。例如:

  1. 您正在网关或其他服务上处理身份验证,但无法更改执行身份验证的方式,因此无法在该位置添加 CSRF 保护。在这种情况下,您需要从身份验证令牌中提取 CSRF 令牌并将其与 CSRF 标头一起转发到目标服务进行处理。这意味着您将需要在每项服务中进行 CSRF 保护,这不是一件好事。您不能保证每项服务都会执行此检查。此外,您将需要担心服务间通信。在存在特定标头的情况下禁用 CSRF 保护是可能的,但其本身可能存在安全风险。
  2. 您没有在网关上执行身份验证,或者您没有网关,客户端凭据(身份验证令牌/cookie)被转发到请求链中的每个服务,并且每个服务都需要处理它自己的身份验证/CSRF 保护。和上面一样,你不能保证每个服务都会这样做,但上面概述了处理 CSRF 的方法。

处理 CSRF 的另一种方法是不为身份验证令牌使用 cookie,而是使用标头来传递身份验证令牌。如果出现 XSS 漏洞,这将使身份验证令牌更容易被盗。可以在此处找到有关此困境的文章。

CSRF 只是浏览器的问题(以及在移动应用程序中嵌入浏览器(如 Web 视图)的应用程序),因此无需为机器对机器通信实施保护,因为它们使用 HTTP 客户端库和硬编码 URL,因此没有让他们像使用普通浏览器(img例如带有标签)一样“浏览”易受 CSRF 攻击的端点的方法。

就普通客户端而言,即使您的微服务可以从外部访问,也不应该成为问题,因为它的身份验证系统应该只允许授权客户端(其他微服务、移动应用程序等),即使客户被欺骗访问其 API 端点时,它不应该有正确的凭据来对其进行身份验证(除非您面向客户的 API 密钥或 cookie 可以以某种方式用于内部微服务,这是一个坏主意,您应该防止这种情况发生)。