WebSocket需严格校验Origin头、绑定用户会话、启用子协议校验、限制连接生命周期及权限粒度,防止CSWSH攻击与未授权访问。

WebSocket 本身不直接受同源策略限制,但浏览器在建立 WebSocket 连接时会发送 Origin 请求头,服务端必须校验该字段,否则可能被恶意页面发起跨站 WebSocket 连接(Cross-Site WebSocket Hijacking, CSWSH),进而窃取或操纵用户会话数据。
严格校验 Origin 请求头
服务端在 WebSocket 握手阶段(HTTP Upgrade 请求)必须检查 Origin 头是否属于可信域名。不能仅依赖 Referer,也不能忽略 Origin 或简单允许通配符(如 *)。
- 明确白名单:只接受预定义的前端域名,例如
https://app.example.com、https://staging.app.example.com - 拒绝空 Origin 或非 HTTPS 的 Origin(开发环境可临时放宽,但生产环境必须强制 HTTPS)
- Node.js(ws 库)示例:
const wss = new WebSocket.Server({<br> noServer: true<br>});<br>server.on('upgrade', (req, socket, head) => {<br> if (!['https://app.example.com', 'https://admin.example.com'].includes(req.headers.origin)) {<br> socket.destroy();<br> return;<br> }<br> wss.handleUpgrade(req, socket, head, (ws) => {<br> wss.emit('connection', ws, req);<br> });<br>});
结合身份认证与会话绑定
Origin 校验仅防“谁连你”,不能防“谁在连”。需确保 WebSocket 连接代表的是合法已登录用户。
- 握手请求中携带认证凭证(如带 HttpOnly 的 session cookie),服务端验证 session 有效性并关联到 WebSocket 实例
- 避免在 URL 中传递 token(如
ws://...?token=xxx),易泄露至日志、代理或 Referer - 连接建立后,立即通过 WebSocket 发送一次认证帧(如
{"type":"auth","token":"..."}),服务端验证后才允许后续业务消息
启用子协议(subprotocol)并校验
利用 WebSocket 的 Sec-WebSocket-Protocol 头声明客户端支持的子协议,服务端只接受已知且受信的协议名,可增加一层识别和过滤能力。
- 前端创建时指定:
new WebSocket('wss://api.example.com/ws', ['myapp-v1']) - 服务端校验:
if (!req.headers['sec-websocket-protocol']?.split(',').map(s => s.trim()).includes('myapp-v1')) {<br> socket.destroy();<br> return;<br>} - 虽不能替代 Origin 或身份校验,但可辅助识别非法客户端(如 curl 或自写脚本未设置该头)
限制连接生命周期与权限粒度
最小权限原则适用于 WebSocket:按需授权、及时关闭、避免长时高权会话。
- 设置合理的 ping/pong 超时(如 30 秒无响应即断开),防止连接长期闲置被复用
- 对不同用户角色限制可订阅的频道或可执行的操作(如普通用户不能 subscribe to
admin:logs) - 服务端记录连接 ID、用户 ID、IP、时间戳,便于审计异常行为
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










