Socket.IO 客户端安全

信息安全 网络套接字 节点.js
2021-09-03 08:42:38

我是 Node.js 和 Socket.IO 的新手。根据文档,客户端代码类似于:

<script src="/socket.io/socket.io.js"></script>
<script>
  var socket = io('http://localhost:3000');
  socket.on('news', function (data) {
    console.log(data);
    socket.emit('my other event', { my: 'data' });
  });
</script>

它简单易行,但尽管它非常适合本地测试,但我不确定在实时页面上是否真的安全,因为它会暴露服务器的事件信息。

如何在这样的页面上隐藏敏感信息?

3个回答

Socket.io 创建一个WebSocket,并且 WebSockets 遵循正常的同源策略规则。但是,可以使用通常称为 CORS 的 HTTP 标头使WebSocket 成为跨域资源。Access-control-allow-origin如果由于某种原因 CORS 被用于创建跨域 WebSocket,那么这个WebSocket 可能会被一个不受信任的域劫持

此外,WebSocket 与任何其他 API 一样,将应用程序逻辑暴露给攻击者。确保您解决了常见的 Web 应用程序漏洞,例如OWASP Top 10中的漏洞。特别值得关注的是不安全的直接对象引用注入攻击以及损坏的身份验证和会话管理

这个问题有两种通用的解决方案。两种解决方案都基于不向公众发布不应公开的信息的方法。这意味着您必须在应用程序中实现某种身份验证机制,例如创建新会话(和新的临时会话密钥)的登录表单。不用说,您还应该使用https/wss而不是http/ ws

第一种方法是仅发布公共事件,并通过单独的通道(例如新的 HTTP 请求)获取私有事件数据。这就是 Stack Exchange 对实时收件箱通知所做的事情:套接字仅用于通知订阅者新的收件箱消息,而实际内容仅在用户单击通知气泡时通过 http(s) 获取。

第二种方法是在存储套接字服务器端之前验证 Socket.IO 连接。在 Socket.IO 中,您可以通过query选项通过握手传递额外的信息。在服务器上,读取此值并仅允许用户在成功验证后创建套接字(示例 接受的答案是 socket.io 0.9,在此处查找 socket.io 1.x)。该密钥应被视为会话 cookie。当用户注销时,与此密钥关联的套接字应该被销毁并且令牌无效。理想情况下,该密钥应该只使用一次(即在第一次使用后失效),但如果连接不可靠并且您必须不断重新连接到 Socket.IO,这在实践中效果不佳。

作为拒绝套接字(方法 2)的替代方法,您还可以接受套接字并使用身份验证详细信息来控制是否允许用户订阅事件或加入房间。如果您在服务器发送事件,客户端只会收到事件,因此如果您不发送事件(例如,因为用户不在广播事件的房间),则不会泄漏信息。

与所有安全问题一样,您必须描述您的安全目标是什么。从谁那里安全?从什么样的访问安全?它需要在多大程度上避免不受欢迎的访问?您愿意添加哪些级别的身份验证和加密来防止不受欢迎的信息查看者?

您在上面设置的方案允许以下内容:

  1. 任何代理都可以使用 websocket 连接到您的服务器并订阅“新闻”事件。news因此,任何人都可以使用该消息广播的任何信息。

  2. 实际上,任何代理都可以使用 websocket 连接到您的服务器并读取它广播到所有连接的套接字的所有消息。这不仅限于news事件。如果您的服务器将数据发送到任何随机连接的 websocket,那么任何随机代理都可以通过 websockets 连接并读取该信息。

  3. 至于以其他方式发送的数据(从您的客户端到服务器),该信息仅对窥探连接的人可用(在您的 ISP 处,通过 Internet 传输到您的服务器所在的数据中心,在数据中在它到达您的服务器或任何可以物理访问您的服务器的人之前居中。如果外部代理无法访问数据包正在传输的传输,则这些数据不容易获得。


关于如何使数据更安全的简短答案与大多数安全问题几乎相同。

  1. 保护访问,在授予访问权限之前需要某种强登录。

  2. 使用加密(例如由适当证书支持的 SSL)保护传输。

  3. 仅在已实施适当安全措施的渠道上发送需要安全措施的信息。


在互联网上,不存在只能由您自己的网页访问的基于服务器的 API 或 websocket 访问。从您的网页访问只是从 Internet 上的某个随机端点进行的访问,并且在预期的浏览器页面、拥有自己的连接工具的黑客或 Internet 上试图访问您的站点的某些流氓服务器之间的访问通常没有区别. 您通常无法区分。有一些技巧可以使第三方访问更加麻烦(例如在必须使用的每个网页中包含不断变化的凭据),但是如果没有上述三个安全租户,它就不是真正的安全。