怎么防止网站用户的Session被中间人攻击劫持?

东方瑞芳 阅读 22

最近在开发一个电商网站,用户登录后发现偶尔会出现异地登录提示。我检查了服务器日志,发现有几个不同IP访问了同一个Session ID。已经设置了Secure; HttpOnly属性,但问题还是存在,这是怎么回事?

尝试过在Nginx强制HTTPS,后端用Node.js设置了:


res.cookie('sessionID', token, {
  httpOnly: true,
  secure: true,
  sameSite: 'strict'
});

但抓包工具仍然能截取到未加密的Cookie(虽然浏览器显示被正确设置了)。可能是配置哪里漏了吗?有没有其他防护措施能彻底避免Session被劫持?

我来解答 赞 3 收藏
二维码
手机扫码查看
2 条解答
路阳 Dev
从你的描述来看,问题可能出在HTTPS的配置或者传输过程中某些环节没完全加密。抓包工具还能截取到未加密的Cookie,说明流量在某个环节还是明文的。性能上,我们得确保每个环节都严格走HTTPS,并且需要增加额外的防护机制。

首先检查Nginx的配置,确保所有HTTP请求都被强制重定向到HTTPS,可以用这个配置:

server {
listen 80;
server_name yourdomain.com;
return 301 https://$host$request_uri;
}

server {
listen 443 ssl;
server_name yourdomain.com;

ssl_certificate /path/to/your/fullchain.pem;
ssl_certificate_key /path/to/your/privkey.pem;

ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
}


另外确认你的SSL证书链完整,不然某些客户端可能会降级到HTTP。用 openssl s_client -connect yourdomain.com:443 -showcerts 检查一下证书链是否正常。

接着是Session绑定的问题。即使设置了 SecureHttpOnly,攻击者仍然可以通过网络嗅探拿到Session ID然后尝试重放。建议增加一个用户标识绑定,比如把用户的IP或者User-Agent和Session关联起来。Node.js里可以这样做:

const crypto = require('crypto');

function generateToken(userId, userAgent) {
const hash = crypto.createHmac('sha256', 'your-secret-key')
.update(userId + userAgent)
.digest('hex');
return hash;
}

// 在登录时生成token
const token = generateToken(user.id, req.headers['user-agent']);
res.cookie('sessionID', token, {
httpOnly: true,
secure: true,
sameSite: 'strict'
});

// 验证时检查
function validateToken(userId, userAgent, token) {
const expectedToken = generateToken(userId, userAgent);
return crypto.timingSafeEqual(Buffer.from(token), Buffer.from(expectedToken));
}


这样即使攻击者拿到了Session ID,没有正确的User-Agent也无法通过验证。

最后提醒一点,别忘了定期轮换Session ID,尤其是在敏感操作前后。比如支付、修改密码这些场景下,直接重新生成一个新的Session ID,旧的直接废弃。这样能有效减少Session被劫持后的影响范围。

性能上这些措施的开销都不算大,但安全性提升很明显,建议尽快加上去。
点赞
2026-02-19 23:09
爱欢酱~
你这配置没问题,但抓包工具能截取未加密Cookie,说明请求本身没加密,**必须强制所有请求走HTTPS**,否则中间人可以轻易截取流量。

改成这样:

# Nginx配置
server {
listen 80;
return 301 https://$host$request_uri;
}


再检查Node.js是否信任反代的X-Forwarded-Proto头:

app.set('trust proxy', 1);


最后,考虑加一个**绑定用户IP或User-Agent**的二次校验,防止Session被横向移动。
点赞 2
2026-02-03 20:01