6月1日 02:20

WebSocket 握手过程是怎样工作的?HTTP 升级机制与安全防御

WebSocket 握手是基于 HTTP 的协议升级过程。客户端发送一个特殊的 HTTP GET 请求,携带 Upgrade: websocketConnection: Upgrade 头部,表明要切换协议。同时带上 Sec-WebSocket-Key(16字节随机值的 Base64 编码)和 Sec-WebSocket-Version(通常为13)。服务端验证请求合法后,返回 101 Switching Protocols 状态码,并附带 Sec-WebSocket-Accept 头部,其值由客户端 Key 拼接固定 GUID 258EAFA5-E914-47DA-95CA-C5AB0DC85B11,经 SHA-1 哈希后再 Base64 编码得到。握手完成后,连接不再走 HTTP 协议,而是切换为 WebSocket 帧格式进行双向通信。还可通过 Sec-WebSocket-Protocol 协商子协议,Sec-WebSocket-Extensions 协商扩展(如压缩)。

追问

Sec-WebSocket-Accept 为什么要拼接固定 GUID?

这是 RFC 6455 的设计:GUID 是公开的常量,不提供加密作用,而是确保握手方确实理解 WebSocket 协议——普通 HTTP 客户端不会拼接这个 GUID,从而防止误升级。服务端无需维护状态,只需按规则计算即可验证。

javascript
const crypto = require('crypto'); function acceptValue(key) { return crypto.createHash('sha1') .update(key + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11') .digest('base64'); }

什么是 CSWSH 攻击?如何防御?

CSWSH(Cross-Site WebSocket Hijacking)指恶意网页利用浏览器自动携带 Cookie 的特性,向目标站点发起 WebSocket 连接,冒充已登录用户。防御核心是服务端验证 Origin 头部,拒绝非白名单来源的升级请求。此外,避免仅依赖 Cookie 鉴权,应结合 Token 机制(如在 URL 参数或首条消息中携带)。

wss 和 ws 的区别是什么?

ws:// 是明文传输,wss:// 在 TCP 之上加了 TLS 加密层,等同于 HTTP 与 HTTPS 的关系。生产环境必须使用 wss,否则握手和后续帧数据均可被中间人窃听或篡改。TLS 还能防止缓存投毒攻击——代理服务器不会将加密流量误判为普通 HTTP 响应并缓存。

握手失败会怎样?

服务端如果不支持 WebSocket 或验证不通过,不会返回 101,而是返回普通 HTTP 响应(如 400/403)。客户端收到非 101 响应后,WebSocket 对象触发 error 事件并关闭连接,不会尝试回退。若需降级为轮询,需在应用层自行实现。

标签:WebSocket