对于希望防止跨站点请求伪造的 HTTP 应用程序的标准建议是在每个状态更改请求(通常是 POST)中包含一个随机令牌,该令牌在允许状态更改之前由服务器验证。
相同的注意事项是否适用于 WebSocket 连接?使用 WebSockets(或 Socket.IO 或 SockJS 使用的 JSON 轮询等后备传输)的 Web 应用程序是否应该在每次传输时包含由服务器验证的 nonce 以防止 CSRF?
或者是否有针对 WebSockets 的首选缓解策略?
对于希望防止跨站点请求伪造的 HTTP 应用程序的标准建议是在每个状态更改请求(通常是 POST)中包含一个随机令牌,该令牌在允许状态更改之前由服务器验证。
相同的注意事项是否适用于 WebSocket 连接?使用 WebSockets(或 Socket.IO 或 SockJS 使用的 JSON 轮询等后备传输)的 Web 应用程序是否应该在每次传输时包含由服务器验证的 nonce 以防止 CSRF?
或者是否有针对 WebSockets 的首选缓解策略?
使用 websockets (...) 的 web 应用程序是否应该在每次传输时包含由服务器验证的 nonce 以防止 CSRF?
TL;DR:这是可取的,尽管不一定在每次传输(每个连接一次就足够了)并且不是为了防止 CSRF,而是为了防止 XSS。不过,这更像是一种保障,而不是一种严格的必要性。详情如下。
要回答 WebSockets 是否易受 CSRF 攻击,我们必须首先了解允许此类攻击发生的条件:
例如,当站点 A 包含一个指向域 B 的img标记时src,用户代理会接受请求,并传递为域 B 设置的任何 cookie。使用秘密 CSRF 令牌完成的是,部分身份验证数据是包含在 URL 本身中,因此不知道令牌的攻击者无法伪造将被服务器接受的 URL(因为这部分身份验证将失败)。
AFAIK WebSockets 可以打开与任何服务器和端口的连接(免责声明:链接帖子中使用的参考可能已过时)。他们可以拥有自己的 cookie(尽管与 HTTP 页面使用的 cookie 不同 - 因为方案不同)并且 - 如果我对RFC6455的解释是正确的 - 这些 cookie将与连接请求一起发送,无论哪个站点发起请求(尽管服务器可以拒绝来自不同来源的请求)。如果这些 cookie 提供了接受请求所需的所有身份验证,则服务器将接受请求。
因此,要确定是否可以进行基于 WebSocket 的 CSRF 攻击,必须考虑以下问题(尽管我恐怕无法提供明确的答案):
ws或wss作为方案创建 URL 并将其用作标记元素的src或?href那会不会有任何不良的副作用?我知道这很愚蠢,但由于我对这个问题没有答案,我仍然必须提出这种可能性......相同的考虑是否适用于 websocket 连接?
不,websockets 本身没有 cookie,它们只有通过 websocket 连接显式发送的数据。
使用 websockets(或 Socket.IO 或 SockJS 使用的 JSON 轮询等后备传输)的 Web 应用程序是否应该在每次传输时包含由服务器验证的 nonce 以防止 CSRF?
是的,这是特定于实现的。例如,关于授权的 Socket.IO 文档指出:
当服务器接收到连接时,它将开始从请求中收集以后可能需要的数据。这样做有两个原因:
- 用户可能希望根据标头或 IP 地址中的信息授权客户端。
- 并非所有传输在尝试与服务器建立实时连接时都会发送标头,因此我们在内部存储握手数据,因此我们确保用户可以在客户端连接时再次重用此数据。例如,您可能希望从 cookie 标头中读取会话 ID,并为连接的套接字初始化 Express 会话。
因此,除非您对每个用户会话使用 nonce,否则如果您在回退机制的服务器端自动接受 cookie 值,则回退传输可能容易受到 CSRF 的攻击。
或者是否有针对 websockets 的首选缓解策略?
Origin如果在初始 HTTP 握手期间验证了标头,则Websocket 不会受到 CSRF的攻击。因此缓解策略是验证Origin客户端发送的标头。