V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
DongZhe93
V2EX  ›  Node.js

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

  •  
  •   DongZhe93 · 2018-09-25 14:26:55 +08:00 · 4663 次点击
    这是一个创建于 2011 天前的主题,其中的信息可能已经有所发展或是发生改变。
    场景:A 用户登录,劫持到登录后的 Cookie;抓包工具拦截 B 用户请求,修改为 A 用户的 Cookie,再发送请求,服务器返回 A 用户的信息。
    20 条回复    2018-09-26 12:05:32 +08:00
    whypool
        1
    whypool  
       2018-09-25 14:34:17 +08:00
    不能
    其他的后端框架或者语言也不能

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

    https

    cookie 绑定 ua 或者 ip

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

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

    就算你开发客户端,你是选择用经过无数人审计,经过大量实践证明稳定可靠的 TLS,还是要自己重新发明一个全部都是 bug 和安全漏洞的” TLS “?
    wangxiaoaer
        5
    wangxiaoaer  
       2018-09-25 15:24:48 +08:00 via Android
    @DongZhe93 IP 可以校验啊,不过也不是好的办法。4g 网络 IP 会变。
    virusdefender
        6
    virusdefender  
       2018-09-25 15:46:24 +08:00
    @DongZhe93 #3 那无解。。如果尝试解决还是重新发明了一个类似 https 的东西
    zzNucker
        7
    zzNucker  
       2018-09-25 15:51:26 +08:00
    这个不是语言能解决的问题
    Immortal
        8
    Immortal  
       2018-09-25 16:10:16 +08:00
    这个是 http 协议的东西啊 不是语言框架啥的问题 你用 jwt 方式做校验也一样会被劫持 现在最方便的还是上 https
    aqqwiyth
        9
    aqqwiyth  
       2018-09-25 16:56:16 +08:00
    使用长链接 websocket 试试
    dany813
        10
    dany813  
       2018-09-25 17:46:00 +08:00
    https
    libook
        11
    libook  
       2018-09-25 17:52:58 +08:00   ❤️ 1
    既然你提到了“劫持”,那就是前后端通信协议的锅; 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
        12
    DongZhe93  
    OP
       2018-09-25 19:08:29 +08:00
    @libook 电科院黑盒测试暴露的问题,叫水平越权攻击。内部系统,目前也不打算换 https,也搜索了一些没有解决方案,但并没有找到合适的解决方法。
    blless
        13
    blless  
       2018-09-25 19:47:35 +08:00 via Android
    签名呗…
    blless
        14
    blless  
       2018-09-25 19:51:09 +08:00 via Android
    每次请求对所有参数排序哈希,然后混个盐,开放 api 标准做法啊
    mytry
        15
    mytry  
       2018-09-25 20:45:58 +08:00
    就算上了 https 仍会被劫持,因为 —— 没加 secure 同样会在三方站被劫持。

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

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

    另外算法必须强烈依赖 DOM API,并且内部有检查控制台、常用模拟器等调试环境,防止被整个算法被拔走当做黑盒调用。当然后期还是依靠对抗,破解了再更新,必要的话加上行为采集,防止被自动化工具计算。
    AlisaDestiny
        16
    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
        17
    mytry  
       2018-09-25 20:53:53 +08:00
    另外漏了一点,需要在 cookie 之外的本地存储里放一些持久信息,例如 localStorage、etag、cache 等。这样必须全都获取到才行。
    tanranran
        18
    tanranran  
       2018-09-25 23:49:59 +08:00
    @mytry #17 然后 IP 绑定 cookie,然后图片验证码
    KingPL
        19
    KingPL  
       2018-09-26 10:05:25 +08:00
    签名~ 看描述猜想是获取个人相关业务的时候请求,后台是根据 seesion 获取当前用户;前端隐藏提交 userId 参数,参数加盐非对称加密,还要校验签名
    libook
        20
    libook  
       2018-09-26 12:05:32 +08:00
    @DongZhe93 为什么不用 HTTPS 呢?可以用 Let ’ s Encrypt 的免费证书,或者只有有限的人会用的话也可用自签证书,直接在代理服务器上部署证书还不需要改程序。自己 Hack 最终做到极致也是重做了个山寨版的 HTTPS。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3485 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 10:54 · PVG 18:54 · LAX 03:54 · JFK 06:54
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.