根据 Spring Security 文档,对于 Websocket,在服务器级别实现了 SOP,这与浏览器实现 SOP 的常规 http 相反。但是,Spring Security 还需要 CONNECT 消息的 CSRF 令牌,以确保 SOP。 来自 Spring 文档:
任何入站 CONNECT 消息都需要有效的 CSRF 令牌来实施同源策略。
如果在服务器级别实现SOP,CSRF攻击如何发生?连接请求是一个简单的请求吗?就算是,那不就被服务器拒绝了吗?据我所知,在浏览器中篡改原始标头是不可能的。 我也检查了这个线程,但仍然不清楚服务器端的来源检查是否足够。
任何帮助表示赞赏!
由于没有人能给我答案,我将尝试在这里发布我的理由,说明为什么检查服务器上的 Origin 标头足以保证 Websocket 的安全。请注意,我不是安全/网络套接字专家。 首先我们需要了解为什么在 http 请求时需要 CSRF 令牌以及为什么浏览器实现的 SOP 还不够。
浏览器不会对简单请求强制执行SOP,这意味着请求将与cookie一起发送并由服务器处理,但响应将无法读取。由于请求已得到处理,损害已经造成。为了克服这个限制,引入了 CSRF 代币作为防御机制。
我想说,即使对于 http 请求,服务器端 Origin 检查也应该足以实现 CSRF 保护,因为如果实施正确,它应该在处理发生之前阻止请求。对于 websockets 来说应该更安全,因为使用 websockets 是一个两步过程:
因为我们检查服务器上的源,不良行为者永远不会到达步骤 2,因为请求将被步骤 1 阻止。
[OWASP][1] 将服务器端来源检查移至深度防御策略列表中。据我从 [this][2] 链接了解,这是由于某些浏览器(如 IE11)在极少数情况下不发送 Origin 标头。显然,这些案例很少见,足以被忽视。另外,我假设如果没有设置 Origin 标头,一个好的实现将默认阻止请求(希望 Spring Security 能够做到这一点)。
您可能会问,如果 Spring Security 提供了开箱即用的 CSRF 令牌,为什么还要麻烦地不使用 CSRF 令牌呢? 原因是我在使用 websockets 的微服务前面添加了 Spring Cloud Gateway,并且我在网关级别实现了安全性(包括 CSRF 令牌)。然而,虽然 REST API 是安全的(因为网关通过 TokenRelay 过滤器发送授权标头,这使得微服务跳过 CSRF 验证,本质上信任网关),但它对 Websocket 没有影响。此外,在微服务中启用 Websocket 安全性将启用 CSRF 令牌,但请求将失败,因为我正在发送网关的 CSRF 令牌(有 2 个单独的令牌存储库,一个用于网关,一个用于微服务)。我可能只会针对这个主题添加另一个问题。 结果,我发现自己被迫放弃 CSRF 而使用 Websocket,并质疑它是否真的需要。