防御websocket攻击必须服务端握手校验、连接生命周期限流、边缘层分流三层并重:握手阶段校验origin与jwt,每连接独立限流并设心跳超时,nginx/cdn前置限连且监控联动。

直接结论:单靠客户端拦截或前端代码毫无意义,防御必须落在服务端握手校验、连接生命周期限流、边缘层分流这三层,缺一不可。
WebSocket握手阶段必须校验Origin和JWT
攻击者能轻易伪造 ws:// 连接请求,但无法绕过服务端对 HTTP Upgrade 请求头的检查。不校验就等于敞开大门。
- 拒绝空
Origin、http://协议或未知域名(如Origin: https://evil.com) - 从
Authorizationheader 或Sec-WebSocket-Protocol提取 JWT,用同步方式验证签名与有效期——不能异步延迟响应,否则会放大连接堆积 - 绝对禁止把 token 放在 URL 查询参数里(如
wss://api/ws?token=xxx),日志、代理、Referer 都可能泄露 - Spring WebSocket 中需显式配置
setAllowedOrigins(Arrays.asList("https://app.example.com")),默认*是高危配置
每个连接必须绑定独立限流器和心跳超时
长连接不等于“永远在线”,没约束的连接就是资源黑洞。共享计数器(如全局限流 1000 QPS)会导致误杀,必须 per-connection 约束。
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
- 使用滑动窗口(非令牌桶)为每个新连接初始化独立限流器,例如每秒最多 3 条业务消息,超限立即
close(4408, "rate limited") -
ping超时设为 35 秒,服务端发ping后未收到pong就断开,避免“僵尸连接”占着 fd 和内存不放 - 连接建立后 2 秒内必须收到认证帧(如
{"type":"auth","token":"..."}),否则关闭,防止恶意客户端只连不说话 - Netty + WebSocketServerProtocolHandler 场景下,要在
userEventTriggered()中处理WebSocketServerProtocolHandler.HandshakeComplete事件后立刻挂载限流逻辑
Nginx 或 CDN 必须前置做连接数限制
应用层再强也扛不住海量 TCP 握手洪泛。必须把清洗压力卸载到更外层,让恶意流量在抵达你的进程前就被拦住。
- Nginx 配置中启用
limit_conn,注意用$binary_remote_addr而非$remote_addr,避免 IPv6 地址哈希冲突 - 若经 Cloudflare,开启 Bot Management 并启用 “Managed Challenge” 模式,对异常 TLS 指纹或高频短连 IP 弹出 JS 挑战
- 反向代理层应拒绝非法 Upgrade 请求:检查
Connection: Upgrade和Upgrade: websocket是否同时存在,缺失任一则 400 返回 - 测试环境可额外加严:对
origin包含localhost或127.0.0.1的请求,强制限流至每分钟 1 个新连接
真正容易被忽略的是:限流策略必须和监控联动。光配了 limit_conn 但没采集 limit_conn_rejected 指标,等于没装仪表盘;光写了 ping 超时逻辑但没记录断连原因(是超时?还是认证失败?),下次攻击来时你根本分不清是网络抖动还是定向打击。










