token 如何存放才能避免 csrf 攻击 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
NoKey
V2EX    程序员

token 如何存放才能避免 csrf 攻击

  •  
  •   NoKey 2024 年 7 月 23 日 3195 次点击
    这是一个创建于 542 天前的主题,其中的信息可能已经有所发展或是发生改变。
    放 cookie 中,但是后端不读 cookie
    所有请求需要前端把 token 放到 header 中一个参数下
    后端读 header 中的这个参数
    这样是不是就可以放置 csrf 攻击了呢?
    第三方直接通过服务链接带 cookie 过来,因为后端不读取,所以鉴权不通过
    13 条回复    2024-07-30 11:27:42 +08:00
    zzNucker
        1
    zzNucker  
       2024 年 7 月 23 日
    存 cookie, header, html 都可以
    ss098
        2
    ss098  
       2024 年 7 月 23 日
    你是不是在找 OAuth 2.0 Bearer token ?
    yinmin
        3
    yinmin  
       2024 年 7 月 23 日
    常见这 2 种方式吧:
    方式一:csrf token 放服务器的 session ,然后前端传 token (header 、post 参数、get 参数都可以)做对比
    方式二:csrf token 放 cookie 里(设置成 httponly 和 secure),然后前端传 token (header 、post 参数、get 参数都可以)做对比

    方式一的服务器 session 容易丢失,我是推荐方式二,可以做成无服务器状态模式。
    happyxhw101
        4
    happyxhw101  
       2024 年 7 月 23 日
    一般放在 header 里面可以防止 csrf 攻击,
    如果是放在 cookie 里面,那需要单独生成一个 csrf token ,前端用 js 把 csrf token 放在 header 里面,同时生成一个值是 csrf token 的 cookie ,后端收到请求比较 header 和 cookie 里面的值,这种也是常规手段,但也不能做到 100%
    Belmode
        6
    Belmode  
       2024 年 7 月 23 日
    我觉得 CSRF 无非是避免浏览器,在非法跨站请求携带默认参数时,导致的权限问题。那`认证信息`放哪都无所谓了,放 cookie 也可以,放本地存储也可以,提交的时候放 header 也行,放 cookie 也行。只要保证存储和使用时有标记不一样,并且服务端只认带这个标记的`认证信息`。

    楼上说的,Bearer Token 就是。`认证信息`存任何地方都行,但是放在请求头上时,Authorization: Bearer <token>。这样就确保,是自己站点的页面执行了 js 发送的请求,不是跨站请求。

    所以用 OAuth2.0 之类的认证方式,只要提交请求认证信息时做点不一样的操作,都不用特别考虑 CSRF 攻击,因为从机制上已经避免了。
    Belmode
        7
    Belmode  
       2024 年 7 月 23 日
    @Belmode OP 提问中的疑问的答案是肯定的。你那样操作,是可以避免 CSRF 攻击的。
    moon548834
        8
    moon548834  
       2024 年 7 月 24 日
    @Belmode 请教下为什么 token 放 cookie 里可以呢?我理解 header 是 ok 的
    用户 A 请求正常网站 C ,假设用户点了某个钓鱼网站 B ,那么 B->C 的过程不是会把 cookie 信息自动带上吗?

    或者说一个普通的 access_token 放到 cookie 面临的问题不能被一个也在 cookie 中的 csrf token 解决?
    forvvvv123
        9
    forvvvv123  
       2024 年 7 月 25 日
    @happyxhw101

    OP 用这个方法就行,最简单实用的,cookie 双重认证, 你所有的重要请求都在页面上用 js 发 post , 发的时候把 cookie 里面的 token 值带到请求上,放 post 参数、header 里都行;

    你后端收请求的时候:
    1. 先看 cookie 里面有没有 token ,没 token 就拒绝,然后 set-cookie 种个随机数 token ;
    2. 再看请求里面带没带和 cookie 一样的 token ,不一样就拒绝;

    对 csrf 的问题就解决了;


    网上有很多会结合 xss 和 csrf 考虑的,我个人认为这样复杂了,一般有了 xss 漏洞就不考虑 csrf 了,xss 能做的太多了;有 xss 的问题修 xss 的问题,讨论 csrf 都是要在没 xss 没钓鱼的情况下讨论,不然说不清;
    Belmode
        10
    Belmode  
       2024 年 7 月 26 日
    @moon548834 #8

    首先,我说以下一般实现,现在很多网站或者说产品,都没有专门设置 CSRF token 的,都不是通过这种手段来避免跨站攻击。
    在你例子中,用户从钓鱼网站 B 触发的网站 C 的请求,携带了 Cookie 到目标服务器,但是服务器是不会认可`此次请求已被授权的`,因为不是从网站 C 页面上发起的,所以网站 C 的 JS 没有执行,没有讲 Cookie 中的 token 部分提取出来,放到 Header 中,并拼上`Bearer`之类的符号,所以这次请求,就和用户第一次访问网站 C 一样,是安全的。

    这其中关键在于,网站 C 服务端,不认可从其他网页发起的 http 请求,只认可自己页面的,所以借助 Ouath2.0 令牌模式的机制,避免了 CSRF 。

    当然你自定义任何方式都可以,只要类似我#6 的说法。

    PS1: 理论上令牌可以放到任何位置,但是一般放到 localStorage 里,因为浏览器请求在没有 JS 处理的情况下,不会携带这些信息,有一定安全性。
    PS2: 我说的只是一种最简单的模型理论,实际上企业中,预防 CSRF 的手段特别多,因为用户信息和权限的校验步骤非常多,也非常复杂,不是那一种方式就能完成的,都是多种手段并用。
    PS3:V 站用了 CSRF token ,并且这个 token 有实效,过期了,页面都直接时效了,可以参考。
    moon548834
        11
    moon548834  
       2024 年 7 月 26 日
    "在你例子中,用户从钓鱼网站 B 触发的网站 C 的请求,携带了 Cookie 到目标服务器,但是服务器是不会认可`此次请求已被授权的`,因为不是从网站 C 页面上发起的"

    这个你说的是同源检查吧,如果 C 不做同源检查,那应该是认可的..

    ref: https://tech.meituan.com/2018/10/11/fe-security-csrf.html
    NoKey
        12
    NoKey  
    OP
       2024 年 7 月 27 日
    @moon548834 后端不仅仅通过 cookie 里面的 token 进行鉴权相关识别,是不是就没问题了,不用管是不是同源?
    moon548834
        13
    moon548834  
       2024 年 7 月 30 日
    @NoKey 应该是吧,总之我还是认为把 token 放 header 里是最佳实践
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2799 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 52ms UTC 13:52 PVG 21:52 LAX 05:52 JFK 08:52
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86