什么是Websocket?
- Websocket是一种通信协议
- 通过HTTP发起的,全双工
- 用于现代Web应用程序,流式传输数据
Websocket和HTTP区别
- HTTP作为老牌协议,客户端发送请求报文,服务器回复响应报文。通常,响应立即发生,表示事物完成。即使网络保持打开状态,也将用于请求和响应的单独事物
- WebSocket通过HTTP发起,并且是长期存在的,消息随时可以向另一方发送,本质上不具有事务性,所以存在空闲状态。此外,Websocket对于需求低延迟服务的消息情况下十分讨喜,比如金融数据实时传输
Websocket如何建立
Websocket通常使用客户端JavaScript脚本创建var ws = new WebSocket("wss://normal-website.com/chat");
和HTTP一样,存在加密证书:ws协议属于未加密连接,wss协议属于加密连接。
为了建立连接,浏览器和服务器会通过HTTP执行WebSocket握手,浏览器发送一个握手请求:
GET /chat HTTP/1.1
Host: normal-website.com
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: wDqumtseNBJdhkihL6PW7w==
Connection: keep-alive, Upgrade
Cookie: session=KOsEJNuflw4Rd9BDNrVmvwBF9rEijeE2
Upgrade: websocket
服务器返回一个WebStock握手响应:
HTTP/1.1 101 Switching Protocols
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Accept: 0FFP+2nmNIf/h+4BP36k9uzrYGk=
此时,网络连接保持打开状态,可用于向任一方向发送 WebSocket 消息。
注意
WebSocket 握手消息的几个特性值得注意:
- 请求和响应中 的Connection和Upgrade标头表明这是一次 WebSocket 握手。
- Sec-WebSocket-Version请求头指定WebSocket协议版本的客户端希望使用。通常是13.
- Sec-WebSocket-Key请求报头包含Base64编码的随机值,这应该在每个握手请求是随机产生的。
- Sec-WebSocket-Accept响应报头包含在提交的值的散列Sec-WebSocket-Key请求头,具有在协议规范中定义的特定的字符串串联。这样做是为了防止错误配置的服务器或缓存代理导致误导性响应。
WebSocket消息是怎样的?
一旦建立了 WebSocket 连接,客户端或服务器就可以在任一方向上异步发送消息。
可以使用客户端 JavaScript 从浏览器发送一条简单的消息,如下所示:ws.send("Peter Wiener");
原则上,WebSocket 消息可以包含任何内容或数据格式。在现代应用程序中,通常使用 JSON 在 WebSocket 消息中发送结构化数据。
例如,使用 WebSockets 的聊天机器人应用程序可能会发送如下消息:
`
{"user":"Hal Pline","content":"I wanted to be a Playstation growing up, not a device to answer your inane questions"}
WebSocket安全漏洞
原则上,几乎所有 Web 安全漏洞都可能与 WebSockets 相关:
- 传输到服务器的用户提供的输入可能会以不安全的方式进行处理,从而导致诸如SQL 注入或 XML 外部实体注入等漏洞。
- 一些通过 WebSockets 达到的盲漏洞可能只能使用带外 (OAST) 技术检测到。
- 如果攻击者控制的数据通过 WebSockets 传输到其他应用程序用户,则可能导致XSS或其他客户端漏洞。
操作WebSocket消息利用漏洞
操纵 WebSocket 消息以利用漏洞
大多数影响 WebSocket 的基于输入的漏洞都可以通过篡改 WebSocket 消息的内容来发现和利用。
例如,假设聊天应用程序使用 WebSockets 在浏览器和服务器之间发送聊天消息。当用户输入聊天消息时,会向服务器发送如下所示的 WebSocket 消息:
{"message":"Hello Carlos"}
消息的内容(再次通过 WebSockets)传输到另一个聊天用户,并在用户的浏览器中呈现如下:
<td>Hello Carlos</td>
在这种情况下,如果没有其他输入处理或防御在起作用,攻击者可以通过提交以下 WebSocket 消息来执行概念验证 XSS 攻击:
{"message":"<img src=1 one rror='alert(1)'>"}
操纵 WebSocket 握手利用漏洞
某些 WebSockets 漏洞只能通过操纵 WebSocket 握手来发现和利用。这些漏洞往往涉及设计缺陷,例如:
- 错误地信任 HTTP 标头以执行安全决策,例如X-Forwarded-For标头。
- 会话处理机制中的缺陷,因为处理 WebSocket 消息的会话上下文通常由握手消息的会话上下文决定。
- 由应用程序使用的自定义 HTTP 标头引入的攻击面。
使用跨站 WebSockets 来利用漏洞
当攻击者从攻击者控制的网站进行跨域 WebSocket 连接时,就会出现一些 WebSockets 安全漏洞。这被称为跨站点 WebSocket 劫持攻击,它涉及利用WebSocket 握手中的跨站点请求伪造( CSRF ) 漏洞。这种攻击通常会产生严重的影响,允许攻击者代表受害用户执行特权操作或捕获受害用户有权访问的敏感数据。
如何保护 WebSocket 连接
为了最大限度地降低 WebSockets 产生的安全漏洞的风险,请使用以下准则:
- 使用wss://协议(基于 TLS 的 WebSockets)。
- 硬编码 WebSockets 端点的 URL,当然不要将用户可控的数据合并到这个 URL 中。
- 保护WebSocket握手消息免受CSRF攻击,避免跨站WebSockets劫持漏洞。
- 将通过 WebSocket 接收的数据视为双向不可信数据。在服务器端和客户端安全地处理数据,以防止基于输入的漏洞,例如 SQL 注入和跨站点脚本。