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

2019-09-01 00:51:17 +08:00
 fourstring

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

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

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

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

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

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

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

我只找到使用改变浏览地址发送 get 请求的攻击方式…
或者方便的话给我个例子?
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
2019-09-01 10:36:10 +08:00
#1 说的,既然请求后端域名不带 cookie 那也没必要防范 CSRF 了
然而真正情况是,你会使用某些跨域方法来请求后端接口并且肯定需要带上 Cookie,比如 CORS 的 access-control-allow-credentials,所以最终用 token 防范 CSRF 的话还是和文档里说的是同一种情形
jugelizi
2019-09-01 10:36:24 +08:00
即便这样 登录的时候返回 csrf 的 token 即可啊 前端自己存储 然后自己加到 header
ochatokori
2019-09-01 12:59:58 +08:00
@oott123 #6 对哦,我都忘记普通的表单是会跳到 action 的,脑筋转死了嘻嘻
jybox
2019-09-02 11:27:01 +08:00

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

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

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

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

© 2021 V2EX