一、WebSocket通信安全威胁及优化措施
- 跨站WebSocket劫持(CSWSH)
- 威胁:攻击者利用用户已认证的会话,通过诱使用户访问恶意网站,劫持WebSocket连接,以用户身份发送和接收数据。
- 优化措施:
- 使用HTTP-only Cookies:设置
HttpOnly
属性,使Cookies只能通过HTTP协议传输,不能被JavaScript访问,降低XSS攻击窃取Cookie用于CSWSH的风险。
- 添加额外认证机制:在WebSocket连接时,除了依赖Cookie认证,还添加自定义的认证令牌(token)。例如在前端生成一个基于时间戳和用户信息的签名,在服务器端验证签名的有效性。
- 限制WebSocket源:在服务器端配置允许连接的源(origin),只允许合法的前端域名建立WebSocket连接。在Node.js中使用
ws
库可以这样做:
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });
wss.on('connection', function connection(ws, req) {
const origin = req.headers.origin;
const allowedOrigins = ['http://allowed-domain.com', 'https://allowed-domain.com'];
if (!allowedOrigins.includes(origin)) {
ws.close(1008, 'Not allowed origin');
return;
}
// 正常处理连接
});
- 中间人攻击
- 威胁:攻击者在通信双方之间拦截、篡改或伪造数据。
- 优化措施:
- 使用TLS/SSL加密:部署HTTPS协议,确保WebSocket连接建立在加密通道上,防止数据被中间人窃听和篡改。
- 证书验证:在客户端(前端)验证服务器证书的有效性,确保连接到的是真正的服务器,而不是中间人伪造的服务器。在JavaScript中,可以通过设置
WebSocket
的ca
选项来验证证书(在Node.js作为客户端时)。
二、WebSocket连接异常断开的故障处理
- 前端(JavaScript)故障处理
- 实现思路:使用
close
事件监听连接断开,然后尝试重新连接。同时,设置一个计数器来控制重连次数,并在每次重连之间添加一定的延迟,避免过度请求。
- 关键代码示例:
let webSocket = new WebSocket('ws://your-server-url');
let reconnectCount = 0;
const maxReconnects = 5;
const reconnectDelay = 1000; // 1秒
webSocket.onclose = function (event) {
if (reconnectCount < maxReconnects) {
setTimeout(() => {
webSocket = new WebSocket('ws://your-server-url');
reconnectCount++;
}, reconnectDelay * (1 + reconnectCount));
}
};
webSocket.onerror = function (error) {
console.error('WebSocket error:', error);
};
- 服务器端故障处理
- 实现思路:在服务器端,监听连接断开事件,清理相关资源,并记录断开连接的客户端信息。对于需要确保数据完整性的情况,可以在连接断开时检查未完成的数据传输,并进行相应处理,如重试发送或标记为待处理。
- 关键代码示例(以Node.js的
ws
库为例):
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });
wss.on('connection', function connection(ws) {
ws.on('close', function close(code, reason) {
console.log('Connection closed with code %d and reason %s', code, reason);
// 清理资源,例如移除客户端相关的定时器等
// 处理未完成的数据传输
});
ws.on('error', function error(err) {
console.error('WebSocket error:', err);
});
});