WebSocket详解

发布时间 2023-08-02 00:39:40作者: JiuYou2020

写在最前面

官方文档

简介

WebSocket是一种网络传输协议,可在单个TCP连接上进行全双工通信,位于OSI模型应用层。WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接,并进行双向数据传输。

特点

  1. WebSocket支持HTTP代理和中介,Websocket与HTTP和HTTPS使用相同的TCP端口,可以绕过大多数防火墙的限制。默认情况下,Websocket协议使用80端口;运行在TLS之上时,默认使用443端口。
  2. 建立在 TCP 协议之上,服务器端的实现比较容易
  3. 较少的控制开销。在连接创建后,服务器和客户端之间交换数据时,用于协议控制的数据包头部相对较小。在不包含扩展的情况下,对于服务器到客户端的内容,此头部大小只有2至10字节(和数据包长度有关);对于客户端到服务器的内容,此头部还需要加上额外的4字节的掩码。相对于HTTP请求每次都要携带完整的头部,此项开销显著减少了。
  4. 更好的二进制支持。Websocket定义了二进制帧,相对HTTP,可以更轻松地处理二进制内容。
  5. 不受同源策略限制,客户端可以与任意服务器通信
  6. 更强的实时性。由于协议是全双工的,所以服务器可以随时主动给客户端下发数据。
  7. 保持连接状态。与HTTP不同的是,Websocket需要先创建连接,这就使得其成为一种有状态的协议,之后通信时可以省略部分状态信息。而HTTP请求可能需要在每个请求都携带状态信息(如身份认证等)。
  8. 可以支持扩展。Websocket定义了扩展,用户可以扩展协议、实现部分自定义的子协议。如部分浏览器支持压缩等。
  9. 更好的压缩效果。相对于HTTP压缩,Websocket在适当的扩展支持下,可以沿用之前内容的上下文,在传递类似的数据时,可以显著地提高压缩率。

ps:这是对特点中不太理解处的补充

  1. 如何理解WebSocket支持HTTP代理和中介呢?(握手过程)

    • 为了确保WebSocket协议在现有HTTP基础设施上能够运行,WebSocket的连接建立采用了一种逐步的方式。在WebSocket建立连接之前,客户端与服务器之间首先使用HTTP协议进行初始通信。
    • 在HTTP协议中,当客户端希望将连接升级为WebSocket时,它会发送一个特殊的HTTP请求,其中包含一个Upgrade头部,以指示服务器希望升级到WebSocket协议。服务器在接收到这样的请求后,可以选择接受或拒绝升级请求。
    • 如果服务器接受升级请求,它会发送一个带有特殊的Upgrade头部的HTTP响应,以便客户端知道连接已经成功升级为WebSocket协议。一旦连接升级完成,WebSocket协议将代替HTTP协议来处理后续的数据传输,允许实时双向通信。
  2. 在查看WebSocket相关博客时,博主十分不理解为什么webSocket不受同源策略限制,解释起来很复杂,下面是简单的原因(与cors,csrf相关)

    • 首先需要了解,普通的AJAX请求方式收到同源策略(SOP)的限制,而WebSockets则没有这个限制,它不需要像CORS那样进行客户端的检查
    • WebSockets是在跨域请求的价值已经被证明的情况下引入的。AJAX是早期的Web请求方式,在当时,浏览器的同源策略(SOP)是一个全面适用的政策。后来的CORS是为了放宽同源策略,以避免破坏现有应用程序的假设而进行的客户端检查,相当于一种CSRF攻击。
    • WebSockets作为一种较新的技术,从一开始就设计支持跨域场景。服务器端的逻辑编写者应该意识到跨域请求的可能性,并进行必要的验证,因此不需要像CORS那样在客户端进行繁重的预防措施。
    • 简单而言,WebSockets认为对跨域请求伪造攻击(CSRF)的处理应该交由服务器端来做,编写者应当意识到其中的风险。

    在这只会,我有去详细了解了一下什么是CSRF,怎么预防CSRF,怎么保护WebSocket端点免受跨站点攻击,先说结论

    • 反CSRF令牌,在客户端发起WebSocket请求时,携带该令牌,服务器进行校验,原理是邪恶网站可以连接到你的WebSocket端点,拿到你登录网站的cookie,但是由于SOP限制,他无法从你登录网站获取反CSRF令牌,所以,他即便可以连接到端点,但是它没有令牌用于校验,需要注意的是,,如果你的网站使用了跨源资源共享(CORS)头部,那么 evil.com 可能通过CORS机制获得权限来获取反CSRF令牌并连接到foo.com的WebSocket端点。
      • 嵌入web应用的html中
      • 通过Rest端点获取
    • Origin标头:简单来说,可以类比黑名单机制
      • 在WebSocket连接握手阶段,服务器检查HTTP请求的Origin标头,验证连接的来源是否是受信任的域。
      • 如果Origin标头验证通过,服务器继续建立WebSocket连接,并在连接期间进行适当的身份验证和授权。
      • 如果Origin标头验证失败,服务器拒绝连接,并不予建立WebSocket连接,从而防止CSRF攻击。
      • Origin标头并不能完全防止其他类型的攻击,例如恶意注入或跨站脚本攻击(XSS)
    • 内容安全策略(CSP):当您访问此网页时,您只能从这组源加载脚本和样式。
      • 对于 WebSocket,CSP 可以防止的唯一类型的攻击是攻击者设法将 JavaScript 注入你的网站,试图打开与攻击者控制的服务器的 WebSocket 连接。
      • 因此,虽然 CSP 确实是一种有价值的安全机制,但它并不能有效抵御 CSRF 攻击。

对比AJAX、http,websocket:

在这里插入图片描述

握手协议

过程详见上面补充第一条

WebSocket 是独立的、创建在TCP上的协议。

Websocket 通过 HTTP/1.1 协议的101状态码进行握手。

为了创建Websocket连接,需要通过浏览器发出请求,之后服务器进行回应,这个过程通常称为“握手”(Handshaking)。

长连接的心跳保持

HTTP长连接只能基于简单的超时
WebSocket连接基于ping/Pong心跳机制维持

基于帧不是基于流(HTTP、TCP)

http是基于流的,ascII字符流的,我们只要保证每个字符是有序的,tcp会保证接收方也是有序的;
每一帧有两种承载数据的方式,一种是承载的字符数据(ascII数据),一种是承载的二进制数据(Binary数据)

消息发送

  1. 客户端发起WebSocket连接:客户端通过在HTTP请求头中添加特定的字段(Upgrade: websocket)来请求与服务器建立WebSocket连接。
  2. 服务器接受WebSocket连接:服务器收到带有WebSocket协议标头的请求后,会进行协议升级,从HTTP协议切换到WebSocket协议,并建立WebSocket连接。
  3. WebSocket连接建立后,双方可以进行双向通信。当客户端想要发送消息给服务器时,它会将消息打包成帧,并通过WebSocket连接发送给服务器。
  4. 消息帧打包:在WebSocket中,消息被分割成一个或多个帧进行传输。每个帧包含了消息的一部分。对于比较小的消息,可能只有一个帧,而对于比较大的消息,则会分成多个帧进行传输。
  5. 帧发送:每个帧都包含一些控制位和标志,其中一个重要的标志是“FIN”(Final Bit)。FIN标志指示这是否是消息的最后一个帧。如果消息只有一个帧,那么FIN标志将被设置为1。如果消息有多个帧,那么第一个帧的FIN标志为0,后续的帧的FIN标志都为0,直到最后一个帧的FIN标志为1。
  6. 帧接收:服务器接收到帧后,会根据帧头部的信息解析出消息,并将消息重新组装。这样服务器就能够正确地获取完整的消息。

掩码处理的时机:

掩码处理是在发送WebSocket消息时进行的。客户端在发送数据时,必须对发送的数据进行掩码处理,并在数据帧中添加掩码字段。而服务器在接收到来自客户端的数据帧时,会检查数据帧的掩码字段,对数据进行解掩码处理,从而得到原始的数据。服务器向客户端发送消息时,同样需要对发送的数据进行掩码处理。

注意:WebSocket协议规定客户端发送的数据帧必须使用掩码,而服务器发送的数据帧不能使用掩码。这是为了增加安全性,防止服务器的数据被篡改。服务器发送的数据帧如果包含掩码字段,则客户端会关闭连接。因此,服务器在发送数据时,不应该使用掩码处理。

参考资料:

  1. https://zh.wikipedia.org/wiki/WebSocket
  2. https://blog.csdn.net/weixin_46908367/article/details/109562072
  3. https://dev.solita.fi/2018/11/07/securing-websocket-endpoints.html
  4. https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html
  5. https://security.stackexchange.com/questions/234852/why-websockets-doesnt-apply-sop
  6. https://stackoverflow.com/questions/23674199/why-is-there-no-same-origin-policy-for-websockets-why-can-i-connect-to-ws-loc
  7. https://datatracker.ietf.org/doc/html/rfc6455

如果想

了解websockets防止csrf,可以参考3

了解如何预防csrf可以参考4

了解websockets为什么不支持同源策略,可以参考5、6

了解websockets协议,可以参考7(doge)