【问题标题】:Websocket SecurityWebsocket 安全
【发布时间】:2015-10-12 09:43:31
【问题描述】:

我正在寻找使用 WebSockets 与我们的服务器通信来实现 web(角度)和 iPhone 应用程序。在过去使用 HTTP 请求时,我们使用请求数据、url、时间戳等的哈希值来验证和保护请求。

据我所知,我们无法使用 WebSockets 请求发送标头,因此我想知道如何保护每个请求。

有人有什么想法或好的做法吗?

【问题讨论】:

  • 好问题。我还没有达到使用 websockets 的目的,但这是我迟早想做的事情。我确实找到了这个:auth0.com/blog/2014/01/15/auth-with-socket-io
  • 至少从 https 开始(实际上是 WWS)。 @Rob 的链接是您的下一步。
  • @Rob 谢谢,这是一个开始。但我想要一种可以防止中间人攻击的方法。我真的找不到解决这个问题的方法,过去我将整个请求与请求数据一起散列,因此如果有人更改了请求,服务器就会知道。我想我可以将数据序列化为字符串并将哈希作为 URL 的一部分传递,但不确定这是否安全/良好做法
  • 一旦建立了 TLS 连接 (wss://),只要客户端验证了服务器的证书,并且服务器安全地验证了客户端,那么这个特定的连接对于 MitM 来说是安全的。 WS 服务器可以使用标头 来帮助验证客户端...当然,所有带有owasp.org/index.php/Authentication_Cheat_Sheet 的规则都完全适用;从不接受非 TLS 连接作为经过身份验证,并且身份验证 cookie 必须是仅 TLS 和仅 HTTP:对客户端的 javascript 不可用。
  • 另外,如果您确实在 cookie 中使用了会话令牌,另请参阅 owasp.org/index.php/Session_Management_Cheat_Sheet 作为安全身份验证的额外必要条件,同时混合 WebSocket 和 HTTP 流量......(另外,没有空间在上面添加:标头和cookie仅对WS服务器在握手期间可用,因此如果会话令牌因任何原因发生更改(每次用户的身份验证状态更改时都应该更改)WS必须断开连接并重新启动)。

标签: security authentication websocket


【解决方案1】:

为了保护您的消息,请使用基于 SSL/TLS 的 WebSockets(wss:// 而不是 ws://)。不要推出自己的加密货币。

关于身份验证。 HTTP 和 WebSockets 的最大区别在于 HTTP 是无状态协议,而 WebSockets 不是。

使用 HTTP,您必须随每个请求发送标头(cookie、令牌等)。使用 WebSockets,您可以建立连接。在第一次交互中,您可以对客户端进行身份验证,而对于连接的其余部分,您知道客户端已通过身份验证。

Heroku 的人员描述了一种模式,其中客户端使用 HTTP 进行身份验证,获取票证,然后通过 WebSocket 连接将该票证作为第一条消息发送。见https://devcenter.heroku.com/articles/websocket-security

【讨论】:

  • 你能澄清一下吗?这方面的文档确实非常参差不齐。你是说我可以只使用wss:// 并且协议会自动切换到 TLS 吗?需要什么服务器配置?我已经在一些服务器上这样做了,但得到了一个糟糕的400 Bad Request 回复。
  • 当然,您需要设置服务器以确保安全。需要什么服务器配置取决于您使用的服务器。请提出一个单独的问题。不过,我可能帮不了你。
【解决方案2】:

我同意 SSL/TLS wss:// 连接。始终使用加密流量。有几种方法可以实现身份验证。看这里: http://simplyautomationized.blogspot.com/2015/09/5-ways-to-secure-websocket-rpi.html

大多数示例都使用 python 或 nodejs,并针对 Raspberry Pi,但一般概念是值得考虑的好主意。帖子中有指向 SocketRocket 帮助程序库的链接,该库允许您将身份验证插入 auth 标头 (SocketShuttle)。

【讨论】:

    【解决方案3】:

    与服务器进行安全通信包括对双方进行身份验证。如果您需要通过一个通信渠道为不同的用户提供不同的身份验证凭据(这在当今是一种罕见的想法),您将需要单独的身份验证。否则,您只需要提出密钥分配方案(以便您的应用程序知道您的服务器的公钥,并且您的服务器有一个了解客户端公钥的协议,这有很多模式)。

    为此,有一个比 SSL 或您自己的加密货币更宽的选择梯度(尽量避免不惜一切代价编写自己的加密货币)。

    对于堆栈的 webserver-to-browser 部分,SSL 是您唯一的选择,但不应将其视为一种良好的安全措施,每年都会出现越来越多的漏洞、密码退化案例和信任问题。它承载了 20 年糟糕的工程决策和紧急修复的包袱,所以如果你能得到更好的东西 - 这是值得的。不过,对于普通网站来说,这总比没有好。

    在您的移动应用程序中,您可以轻松地使用众多加密库之一,这些库提供与服务器的安全会话消息传递,具有更高的安全保证,无需依赖:

    • https://github.com/mochtu/libsodium-ios, libsodium-ios 是 NaCl 的 ios 包装器,是最好的现代密码库之一,对 ECC 密码学有很多新颖的实现,在学术界受到高度评价圈子,由一个热衷于在任何情况下都有最佳表现的疯子写的(简而言之:我喜欢它:))。

    • Themis,我参与的一个项目,我们的库非常适合 ObjC 的 iOS 版本,以及在 iOS 中通过 websockets 进行安全流量的便捷教程:@ 987654322@

    【讨论】:

      【解决方案4】:

      您应该使用 SSL/TLS 保护您的连接,并使用 https over http 和 wss over ws。为了进行身份验证/授权,您可以将查询参数添加到 websocket 连接,还可以添加用户名/密码等内容。 例如:

      wss://example.com/path?username=password=anotherParam=99ace112-dd56-427e-ba3d-9dd23e9c7551
      

      是的,在 js 中您不能添加任意标头,但您可以将协议和 Sec-WebSocket-Protocol 标头添加到您的 websocket 连接,并在服务器端基于 websocket 协议对用户进行身份验证/授权

      【讨论】:

      • 但是,即使在 WSS 中,URL 也是以明文形式发送的,不是吗?这意味着可以嗅探密码和用户名...
      • 是的,但是您可以通过发送大量查询参数、非常复杂的解码参数以及通过传递您自己发明的模板并在后端验证它们来使其变得更加复杂
      • 是的,在 js 中你不能为 websocket 设置 header。但是你可以设置这个:Sec-WebSocket-Protocol ;) 并检查客户端是否正在发送有效的字符串,如果是,那么你将打开套接字。
      • 但是您也可以只要求客户端在连接后立即使用令牌进行身份验证,如果身份验证失败则关闭套接字。
      • 这不是最佳实践,因为每个人都可以连接并打开大量 HTTP 连接,只会浪费您的资源并使您的服务器非常繁忙。 Sec-WebSocket-Protocol 将用作预连接身份验证方法,它不包含在查询参数中
      猜你喜欢
      • 2012-09-04
      • 2018-11-08
      • 2014-04-24
      • 2018-02-05
      • 2012-07-30
      • 2015-07-13
      • 2015-03-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多