WebSocket劫持(WebSocket Hijacking)漏洞与防护(进阶篇)
字数 2210 2025-12-07 16:59:01

WebSocket劫持(WebSocket Hijacking)漏洞与防护(进阶篇)

1. 漏洞描述
WebSocket劫持是一种利用WebSocket协议安全缺陷的攻击方式。攻击者通过窃取或伪造合法用户的WebSocket连接凭据(如会话Cookie、认证令牌等),冒用用户身份建立恶意WebSocket连接,从而实时窃取用户数据、注入恶意指令或执行未授权操作。与传统的HTTP会话劫持不同,WebSocket劫持直接发生在持久化的全双工通道上,危害更隐蔽且影响持续。

2. 漏洞原理深度剖析

2.1 WebSocket握手与身份验证机制
WebSocket连接通过HTTP/HTTPS协议发起“握手”升级请求。在握手请求中,浏览器会自动附加当前域下的Cookie、Authorization头等凭据。服务器基于这些凭据完成用户认证并建立连接。漏洞根源在于:

  • 缺乏连接级认证:服务器仅在握手阶段验证凭据,后续通信帧中不再校验发送方身份。一旦握手成功,任何能向该连接发送帧的实体都被视为合法用户。
  • 凭据泄露风险:若Cookie未设置HttpOnly、Secure等属性,或存在XSS漏洞,攻击者可轻易窃取凭据。
  • 连接绑定不牢固:服务器未严格绑定WebSocket连接与底层传输层特征(如IP地址、TCP端口),导致连接可被劫持转移。

2.2 典型攻击场景

  • 窃听与数据窃取:劫持连接后,攻击者实时接收服务器推送给用户的所有消息(如聊天内容、交易通知)。
  • 命令注入:向服务器发送伪造的指令帧,冒充用户执行操作(如转账、修改设置)。
  • 消息篡改与重放:拦截并篡改用户与服务器间的数据帧,或重放历史帧以触发重复操作。

3. 漏洞复现与演示

步骤1:环境搭建
假设有一个在线聊天应用,使用WebSocket(ws://chat.example.com/ws)。用户登录后,服务器返回会话Cookie session_id=abc123,并以此建立WebSocket连接。

步骤2:攻击者视角

  • 凭据获取:通过XSS攻击窃取用户的session_id(例如:document.cookie)。
  • 连接建立:攻击者在自己的机器上运行脚本,使用窃取的Cookie发起WebSocket握手:
    const ws = new WebSocket('ws://chat.example.com/ws');
    ws.onopen = () => {
      // 握手成功,连接已被劫持
      ws.send(JSON.stringify({type: "get_history"})); // 窃取聊天记录
    };
    
  • 持续监听:攻击者可保持连接开放,实时接收服务器推送的所有消息。

4. 进阶攻击手法

4.1 跨站WebSocket劫持(CSWSH)
类似CSRF,但针对WebSocket连接。若应用未验证WebSocket握手的Origin头,攻击者可在恶意网站中嵌入脚本,利用用户已登录状态自动建立WebSocket连接(浏览器自动发送Cookie)。攻击脚本示例:

<script>
  const ws = new WebSocket('ws://vulnerable-app.com/ws');
  ws.onopen = () => { ws.send(JSON.stringify({action: "delete_account"})); };
</script>

4.2 连接ID预测与暴力破解
某些应用使用可预测的连接标识符(如递增的ID)。攻击者枚举ID即可接入他人会话。例如:连接URL格式为ws://app.com/ws?conn_id=1001,攻击者遍历conn_id值即可劫持会话。

4.3 中间人(MitM)攻击
在未使用WSS(WebSocket over TLS)的情况下,攻击者可拦截明文握手请求,窃取Cookie或篡改握手数据。

5. 防护与缓解措施

5.1 强化身份验证机制

  • 使用一次性令牌:在WebSocket握手请求的URL或自定义头中携带一次性令牌(如CSRF Token),服务器验证后立即失效。示例:
    const token = getCSRFToken(); // 从页面meta标签获取
    const ws = new WebSocket(`ws://app.com/ws?token=${token}`);
    
  • 双向认证:服务器在连接建立后,可要求客户端发送签名消息或重新认证。

5.2 严格校验握手请求

  • 检查Origin头:验证握手请求的Origin头是否在白名单内,防止跨站请求。
  • 验证Referer头(辅助手段):确保请求来自可信页面。
  • 自定义协议头:添加自定义头(如X-WebSocket-ID)并在服务器端校验,避免仅依赖Cookie。

5.3 绑定连接与会话

  • 记录客户端特征:建立连接时,服务器记录客户端的IP、User-Agent等信息,后续收到帧时校验一致性。
  • 使用信道绑定令牌:将会话与底层TLS通道绑定(如tls-unique),防止连接被迁移。

5.4 安全配置与编码

  • 强制使用WSS:生产环境必须使用TLS加密,防止窃听与篡改。
  • 设置Cookie属性:会话Cookie应设置HttpOnlySecureSameSite=Strict
  • 帧级校验:在关键业务帧中加入消息签名或MAC(消息认证码),确保帧的完整性与来源可信。

5.5 连接生命周期管理

  • 超时与心跳:若连接长时间无活动,强制断开并清理会话。
  • 单一连接限制:同一用户只允许一个活跃WebSocket连接,新连接建立时旧连接自动失效。

6. 安全测试与验证

  • 使用Burp Suite的WebSocket客户端工具,尝试修改握手请求的Origin、Cookie等字段,验证服务器是否拒绝。
  • 编写自动化脚本模拟CSWSH攻击,检查应用是否校验Origin。
  • 审计代码,确保所有WebSocket消息处理函数都验证了用户权限与上下文。

总结:WebSocket劫持的核心风险在于连接身份持续性问题。防护需围绕“强化握手认证、绑定连接特征、加密通信信道、实施帧级安全”四层纵深防御展开,结合业务场景设计恰当的认证与审计机制,确保全双工通道的端到端安全。

WebSocket劫持(WebSocket Hijacking)漏洞与防护(进阶篇) 1. 漏洞描述 WebSocket劫持是一种利用WebSocket协议安全缺陷的攻击方式。攻击者通过窃取或伪造合法用户的WebSocket连接凭据(如会话Cookie、认证令牌等),冒用用户身份建立恶意WebSocket连接,从而实时窃取用户数据、注入恶意指令或执行未授权操作。与传统的HTTP会话劫持不同,WebSocket劫持直接发生在持久化的全双工通道上,危害更隐蔽且影响持续。 2. 漏洞原理深度剖析 2.1 WebSocket握手与身份验证机制 WebSocket连接通过HTTP/HTTPS协议发起“握手”升级请求。在握手请求中,浏览器会自动附加当前域下的Cookie、Authorization头等凭据。服务器基于这些凭据完成用户认证并建立连接。漏洞根源在于: 缺乏连接级认证 :服务器仅在握手阶段验证凭据,后续通信帧中不再校验发送方身份。一旦握手成功,任何能向该连接发送帧的实体都被视为合法用户。 凭据泄露风险 :若Cookie未设置HttpOnly、Secure等属性,或存在XSS漏洞,攻击者可轻易窃取凭据。 连接绑定不牢固 :服务器未严格绑定WebSocket连接与底层传输层特征(如IP地址、TCP端口),导致连接可被劫持转移。 2.2 典型攻击场景 窃听与数据窃取 :劫持连接后,攻击者实时接收服务器推送给用户的所有消息(如聊天内容、交易通知)。 命令注入 :向服务器发送伪造的指令帧,冒充用户执行操作(如转账、修改设置)。 消息篡改与重放 :拦截并篡改用户与服务器间的数据帧,或重放历史帧以触发重复操作。 3. 漏洞复现与演示 步骤1:环境搭建 假设有一个在线聊天应用,使用WebSocket( ws://chat.example.com/ws )。用户登录后,服务器返回会话Cookie session_id=abc123 ,并以此建立WebSocket连接。 步骤2:攻击者视角 凭据获取 :通过XSS攻击窃取用户的 session_id (例如: document.cookie )。 连接建立 :攻击者在自己的机器上运行脚本,使用窃取的Cookie发起WebSocket握手: 持续监听 :攻击者可保持连接开放,实时接收服务器推送的所有消息。 4. 进阶攻击手法 4.1 跨站WebSocket劫持(CSWSH) 类似CSRF,但针对WebSocket连接。若应用未验证WebSocket握手的Origin头,攻击者可在恶意网站中嵌入脚本,利用用户已登录状态自动建立WebSocket连接(浏览器自动发送Cookie)。攻击脚本示例: 4.2 连接ID预测与暴力破解 某些应用使用可预测的连接标识符(如递增的ID)。攻击者枚举ID即可接入他人会话。例如:连接URL格式为 ws://app.com/ws?conn_id=1001 ,攻击者遍历 conn_id 值即可劫持会话。 4.3 中间人(MitM)攻击 在未使用WSS(WebSocket over TLS)的情况下,攻击者可拦截明文握手请求,窃取Cookie或篡改握手数据。 5. 防护与缓解措施 5.1 强化身份验证机制 使用一次性令牌 :在WebSocket握手请求的URL或自定义头中携带一次性令牌(如CSRF Token),服务器验证后立即失效。示例: 双向认证 :服务器在连接建立后,可要求客户端发送签名消息或重新认证。 5.2 严格校验握手请求 检查Origin头 :验证握手请求的Origin头是否在白名单内,防止跨站请求。 验证Referer头 (辅助手段):确保请求来自可信页面。 自定义协议头 :添加自定义头(如 X-WebSocket-ID )并在服务器端校验,避免仅依赖Cookie。 5.3 绑定连接与会话 记录客户端特征 :建立连接时,服务器记录客户端的IP、User-Agent等信息,后续收到帧时校验一致性。 使用信道绑定令牌 :将会话与底层TLS通道绑定(如 tls-unique ),防止连接被迁移。 5.4 安全配置与编码 强制使用WSS :生产环境必须使用TLS加密,防止窃听与篡改。 设置Cookie属性 :会话Cookie应设置 HttpOnly 、 Secure 、 SameSite=Strict 。 帧级校验 :在关键业务帧中加入消息签名或MAC(消息认证码),确保帧的完整性与来源可信。 5.5 连接生命周期管理 超时与心跳 :若连接长时间无活动,强制断开并清理会话。 单一连接限制 :同一用户只允许一个活跃WebSocket连接,新连接建立时旧连接自动失效。 6. 安全测试与验证 使用Burp Suite的WebSocket客户端工具,尝试修改握手请求的Origin、Cookie等字段,验证服务器是否拒绝。 编写自动化脚本模拟CSWSH攻击,检查应用是否校验Origin。 审计代码,确保所有WebSocket消息处理函数都验证了用户权限与上下文。 总结 :WebSocket劫持的核心风险在于连接身份持续性问题。防护需围绕“强化握手认证、绑定连接特征、加密通信信道、实施帧级安全”四层纵深防御展开,结合业务场景设计恰当的认证与审计机制,确保全双工通道的端到端安全。