10. 安全考虑
WebSocket 协议的设计考虑了多种安全威胁. 本章描述主要安全考虑和建议的缓解措施.
10.1 非浏览器客户端
WebSocket 协议可由任何客户端使用, 不限于 Web 浏览器. 非浏览器客户端没有浏览器同源策略的保护.
风险:
- 可以伪造 Origin 头部
- 可以绕过 CORS 限制
- 可以发起大量连接
缓解措施:
- 服务器必须实现额外认证
- 使用令牌验证, 例如 JWT
- 实施速率限制
- 验证所有输入数据
// Server-side verification example
function verifyClient(info, callback) {
const allowedOrigins = ['https://example.com'];
if (!allowedOrigins.includes(info.origin)) {
callback(false, 403, 'Forbidden');
return;
}
const token = info.req.url.split('?token=')[1];
if (!isValidToken(token)) {
callback(false, 401, 'Unauthorized');
return;
}
callback(true);
}
10.2 Origin 考虑
Origin 头部是一项关键安全机制.
推荐做法:
- 验证 Origin: 服务器应验证 Origin 头部
- 白名单方式: 使用白名单而不是黑名单
- 动态 Origin: 如果需要动态 Origin, 使用数据库配置
注意: 非浏览器客户端可以伪造 Origin, 因此不要只依赖 Origin 验证.
10.3 针对基础设施的攻击
缓存投毒攻击
WebSocket 使用掩码机制来防止缓存投毒:
- 所有客户端到服务器的帧 MUST 进行掩码处理
- 服务器到客户端的帧 MUST NOT 进行掩码处理
- 使用随机掩码密钥
中间人攻击
缓解措施:
- 使用 wss:// (TLS 加密)
- 验证服务器证书
- 实现证书固定
// Browser: Always use wss://
const ws = new WebSocket('wss://example.com/socket');
// Server: Enforce TLS
if (!request.connection.encrypted) {
response.status(403).send('TLS required');
}
10.4 实现特定限制
实现应设置合理限制, 以防止资源耗尽攻击.
推荐限制
1. 消息大小限制
const MAX_MESSAGE_SIZE = 1024 * 1024; // 1MB
ws.on('message', (data) => {
if (data.length > MAX_MESSAGE_SIZE) {
ws.close(1009, 'Message too big');
}
});
2. 连接数量限制
const MAX_CONNECTIONS = 10000;
const connections = new Set();
function acceptConnection(ws) {
if (connections.size >= MAX_CONNECTIONS) {
ws.close(1008, 'Server overloaded');
return false;
}
connections.add(ws);
return true;
}
3. 消息速率限制
const RATE_LIMIT = 100; // 100 messages per second
function checkRateLimit(clientId) {
const count = messageCount.get(clientId) || 0;
if (count > RATE_LIMIT) {
return false;
}
messageCount.set(clientId, count + 1);
return true;
}
10.5 WebSocket 客户端认证
认证方法
1. 握手期间的 Cookie 认证 2. URL 参数中的令牌 3. 首条消息认证 4. 自定义握手头部
10.6 连接保密性和完整性
TLS/SSL 要求
生产环境必须使用 wss://:
✅ TLS 优点:
- 加密所有传输数据
- 防止窃听
- 防止数据篡改
- 服务器认证
❌ ws:// 风险:
- 明文传输
- 容易被截获
- 无法验证服务器身份
10.7 无效数据处理
实现必须正确处理无效数据, 以防止安全漏洞.
无效 UTF-8 文本
协议违规
检测到协议违规时, 连接 MUST 被关闭.
10.8 WebSocket 握手对 SHA-1 的使用
握手使用 SHA-1 哈希算法. 虽然 SHA-1 存在已知碰撞攻击, 但在握手上下文中是安全的.
安全检查清单
实现 WebSocket 服务时, 请检查:
- 使用 wss:// (TLS) 而不是 ws://
- 验证 Origin 头部
- 实现认证和授权
- 设置消息大小限制
- 设置连接数量限制
- 实施速率限制
- 验证所有输入数据
- 正确处理协议违规
- 记录安全事件
- 定期更新 TLS 配置
- 监控异常连接模式
- 实现超时机制
参考链接
- 上一章: 9. 扩展
- 下一章: 11. IANA 考虑