在前后端分离且前后端域名不同的情况下如何防御 CSRF? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
fourstring
V2EX    前端开发

在前后端分离且前后端域名不同的情况下如何防御 CSRF?

  •  
  •   fourstring 2019-09-01 00:51:17 +08:00 4963 次点击
    这是一个创建于 2315 天前的主题,其中的信息可能已经有所发展或是发生改变。

    假设前端域名为 a.com 后端域名为 b.com 并且使用 Django REST Framework.

    Django 官方文档中给出的 ajax 请求通过 CSRF 验证的一种方法是:Django 会在回的 cookie 中加上一个 csrftoken cookie,前端可以通过 js 读取这一 cookie 并在发起请求时设置一个额外头部 X-CSRFToken,其值为 csrftoken cookie 的值。

    这种方法在前后端域名相同的情况下能生效,但如果前后端域名不同,则这种方法就失效了。

    这种方法依赖于 cookie 读取的同源性,但在前后端域名不同的情况下,本质上前端发起的请求也是跨域请求,只是是合法的跨域请求罢了,但目前很多防御 CSRF 的方法所依赖的都是 cookie 同源性,在此种情况下根本上就无效了。

    那么在前后端域名不同的情况下应当如何区分合法的请求与非法的请求呢?(都是跨域请求)非常感谢!

    10 条回复    2019-09-02 11:27:01 +08:00
    jybox
        1
    jybox  
       2019-09-01 02:30:02 +08:00   2
    如果服务端不从 Cookie 中读取信息(反正你跨域的话默认也是不会发 Cookie 的)的话,其实就不需要 CSRF Token 了。详见 security.stackexchange.com/questions/62080/is-csrf-possible-if-i-dont-even-use-cookies
    ochatokori
        2
    ochatokori  
       2019-09-01 04:15:10 +08:00 via Android
    把 csrftoken 放在接口处返回而不是放在 set-cookie 处,那每次每次请求让 js 带上这个 token 就好了啊。

    顺便搭车问一下,其实 csrf 攻击是不是只能伪造 get 请求,那么是不是只要遵循 restful 规范不允许 get 方法改变资源就好了
    zdkmygod
        3
    zdkmygod  
       2019-09-01 06:31:50 +08:00 via Android
    @ochatokori 你为什么认为 csrf 为什么只能伪造 get 请求?其他请求照样可以伪造啊。
    至于楼主的问题,我理解了一下,应该就是楼主希望能够跨域读取到 cookie,那你应该去了解一下相关的跨域读取技术,比如说 postMessage ()方法。
    comwrg
        4
    comwrg  
       2019-09-01 09:19:39 +08:00
    1. 设置 Access-Control-Allow-Origin 为你的前端域名
    2. 简单请求不做资源更改
    3. 检查 Origin, Referer
    ochatokori
        5
    ochatokori  
       2019-09-01 09:37:48 +08:00 via Android
    @zdkmygod #3 用其他方法的那必须用 js 吧,但是 js 不能跨域取 cookie 啊

    我只找到使用改变浏览地址发送 get 请求的攻击方式…
    或者方便的话给我个例子?
    oott123
        6
    oott123  
       2019-09-01 10:22:56 +08:00
    @ochatokori <form action="https://httpbin.org/post" id="evil" method="POST"><input type="hidden" name="key" value="value"></form><script>evil.submit();</script>
    whoami9894
        7
    whoami9894  
       2019-09-01 10:36:10 +08:00 via Android
    #1 说的,既然请求后端域名不带 cookie 那也没必要防范 CSRF 了
    然而真正情况是,你会使用某些跨域方法来请求后端接口并且肯定需要带上 Cookie,比如 CORS 的 access-control-allow-credentials,所以最终用 token 防范 CSRF 的话还是和文档里说的是同一种情形
    jugelizi
        8
    jugelizi  
       2019-09-01 10:36:24 +08:00   1
    即便这样 登录的时候返回 csrf 的 token 即可啊 前端自己存储 然后自己加到 header
    ochatokori
        9
    ochatokori  
       2019-09-01 12:59:58 +08:00 via Android
    @oott123 #6 对哦,我都忘记普通的表单是会跳到 action 的,脑筋转死了嘻嘻
    jybox
        10
    jybox  
       2019-09-02 11:27:01 +08:00
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2534 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 36ms UTC 12:10 PVG 20:10 LAX 04:10 JFK 07:10
    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