求助: Express 框架如何预防 cookie 劫持攻击?

2018-09-25 14:26:55 +08:00
 DongZhe93
场景:A 用户登录,劫持到登录后的 Cookie;抓包工具拦截 B 用户请求,修改为 A 用户的 Cookie,再发送请求,服务器返回 A 用户的信息。
4891 次点击
所在节点    Node.js
20 条回复
whypool
2018-09-25 14:34:17 +08:00
不能
其他的后端框架或者语言也不能

方便一点就是 httponly,上 https
virusdefender
2018-09-25 14:53:17 +08:00
http only

https

cookie 绑定 ua 或者 ip

风控
DongZhe93
2018-09-25 15:02:18 +08:00
@virusdefender
httponly 只是在前端没法获取到,在传输中被劫持;
目前不考虑 https 的方式;
绑定 ip 劫持后发请求还是原先的 ip ;
iwtbauh
2018-09-25 15:18:48 +08:00
和什么框架无关

除非单独开发客户端,否则不上 https 无解。lz 的要求好像是”我不穿衣服怎么让别人看不到我的裸体“,就像皇帝的新衣。

就算你开发客户端,你是选择用经过无数人审计,经过大量实践证明稳定可靠的 TLS,还是要自己重新发明一个全部都是 bug 和安全漏洞的” TLS “?
wangxiaoaer
2018-09-25 15:24:48 +08:00
@DongZhe93 IP 可以校验啊,不过也不是好的办法。4g 网络 IP 会变。
virusdefender
2018-09-25 15:46:24 +08:00
@DongZhe93 #3 那无解。。如果尝试解决还是重新发明了一个类似 https 的东西
zzNucker
2018-09-25 15:51:26 +08:00
这个不是语言能解决的问题
Immortal
2018-09-25 16:10:16 +08:00
这个是 http 协议的东西啊 不是语言框架啥的问题 你用 jwt 方式做校验也一样会被劫持 现在最方便的还是上 https
aqqwiyth
2018-09-25 16:56:16 +08:00
使用长链接 websocket 试试
dany813
2018-09-25 17:46:00 +08:00
https
libook
2018-09-25 17:52:58 +08:00
既然你提到了“劫持”,那就是前后端通信协议的锅; HTTPS 是专门被发明用来解决这个问题的;用 HTTP 是明文传输的,完全不可能杜绝中间人劫持。

HTTPS,再加上一系列 HSTS 处理就能满足你的需求,个人评估相比于其他各种 Hack 方案,无论从实施成本、复杂度、有效性还是用户体验上来说,这都是最佳方案。

如果因为各种原因坚持拒绝使用 HTTPS 的话,就只能用一些比较麻烦、效果又不见得好的方案。
楼主想解决的问题:
1. 杜绝中间人拦截 Cookie。这个不用 HTTPS 无解。
2. 杜绝中间人对拦截下来的 Cookie 进行修改。使用非对称加密,前端用公钥加密,后端用私钥解密,中间人没有私钥无法解密 Cookie 内容,也就无法篡改(但这实际上是自己实现了一个简陋版的 HTTPS )。
3. 杜绝已使用的 Cookie 被重复利用。在 Cookie 中包含一唯一识别码,后端查询这个识别码是否被使用过,如果被使用过就返回 403,未被使用过就记录下来并完成后续的业务。这个得搭配非对称加密才好用。

上面这个方案有很多漏洞,比如:
1. 拦截者拦截你的请求,这时候唯一识别码还没有发送到服务器上,拦截下来的 Cookie 是可以用于其他用途的。
2. 还有,拦截者可以不修改你的 Cookie,直接修改你的请求信息,往往也能达到自己的目的。
3. 前端 XSS 攻击连 HTTPS 都防不了,这个是发生在前端的,必须要前端代码上做好安全措施,防止攻击者将攻击程序注入到其他人可以访问到的页面里。
4. 现在好多浏览器都会强烈提示用户未使用 HTTPS 的网站是不安全的,谷歌浏览器会直接在地址栏上显示“不安全”,从某种程度上来说,如果不用 HTTPS,可能会导致用户体验不大好(用户看到提示缺乏安全感)。
DongZhe93
2018-09-25 19:08:29 +08:00
@libook 电科院黑盒测试暴露的问题,叫水平越权攻击。内部系统,目前也不打算换 https,也搜索了一些没有解决方案,但并没有找到合适的解决方法。
blless
2018-09-25 19:47:35 +08:00
签名呗…
blless
2018-09-25 19:51:09 +08:00
每次请求对所有参数排序哈希,然后混个盐,开放 api 标准做法啊
mytry
2018-09-25 20:45:58 +08:00
就算上了 https 仍会被劫持,因为 —— 没加 secure 同样会在三方站被劫持。

另外,就算加了 secure 还是会被劫持,因为还有无数恶意浏览器插件、系统病毒木马等等。。。(之前工作就是做 Web 劫持研究的,系统级的劫持远高于链路~)

所以,最关键的,是需要通过 前端 JS 给 cookie 里重要参数进行签名加密。算法必须是非标准的,否则抓到密钥就被破解了。但也不能自己胡编乱造,在标准算法基础上进行扩展,密码学安全性不是最重要的,算法复杂度才是关键。

另外算法必须强烈依赖 DOM API,并且内部有检查控制台、常用模拟器等调试环境,防止被整个算法被拔走当做黑盒调用。当然后期还是依靠对抗,破解了再更新,必要的话加上行为采集,防止被自动化工具计算。
AlisaDestiny
2018-09-25 20:47:32 +08:00
不用 https 的话判断常用 IP 或者绑定登陆 IP 是正解。
我记得又一次我开了梯子忘记关,然后去删除一个我 forked 的仓库,然后要求我输入密码,但是输入了之后还是被拒绝了,具体的 tips 是什么我忘记了。当时我就截图并且问了下 github。然后我得到的回复是这样的。
https://i.loli.net/2018/09/25/5baa2de325210.png
所以你可以学 github,登陆的 IP 和账户绑定,当操作者的 IP 和登陆时候的不匹配的时候拒绝执行或者再次验证密码。
mytry
2018-09-25 20:53:53 +08:00
另外漏了一点,需要在 cookie 之外的本地存储里放一些持久信息,例如 localStorage、etag、cache 等。这样必须全都获取到才行。
tanranran
2018-09-25 23:49:59 +08:00
@mytry #17 然后 IP 绑定 cookie,然后图片验证码
KingPL
2018-09-26 10:05:25 +08:00
签名~ 看描述猜想是获取个人相关业务的时候请求,后台是根据 seesion 获取当前用户;前端隐藏提交 userId 参数,参数加盐非对称加密,还要校验签名
libook
2018-09-26 12:05:32 +08:00
@DongZhe93 为什么不用 HTTPS 呢?可以用 Let ’ s Encrypt 的免费证书,或者只有有限的人会用的话也可用自签证书,直接在代理服务器上部署证书还不需要改程序。自己 Hack 最终做到极致也是重做了个山寨版的 HTTPS。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/492356

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX