V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
fourstring
V2EX  ›  前端开发

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

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

    假设前端域名为 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   ·   实用小工具   ·   5598 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 07:04 · PVG 15:04 · LAX 23:04 · JFK 02:04
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.