假设前端域名为 a.com 后端域名为 b.com 并且使用 Django REST Framework.
Django 官方文档中给出的 ajax 请求通过 CSRF 验证的一种方法是:Django 会在返回的 cookie 中加上一个 csrftoken cookie,前端可以通过 js 读取这一 cookie 并在发起请求时设置一个额外头部 X-CSRFToken,其值为 csrftoken cookie 的值。
这种方法在前后端域名相同的情况下能生效,但如果前后端域名不同,则这种方法就失效了。
这种方法依赖于 cookie 读取的同源性,但在前后端域名不同的情况下,本质上前端发起的请求也是跨域请求,只是是合法的跨域请求罢了,但目前很多防御 CSRF 的方法所依赖的都是 cookie 同源性,在此种情况下根本上就无效了。
那么在前后端域名不同的情况下应当如何区分合法的请求与非法的请求呢?(都是跨域请求)非常感谢!
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
|
2
ochatokori 2019-09-01 04:15:10 +08:00 via Android
把 csrftoken 放在接口处返回而不是放在 set-cookie 处,那每次每次请求让 js 带上这个 token 就好了啊。
顺便搭车问一下,其实 csrf 攻击是不是只能伪造 get 请求,那么是不是只要遵循 restful 规范不允许 get 方法改变资源就好了 |
3
zdkmygod 2019-09-01 06:31:50 +08:00 via Android
@ochatokori 你为什么认为 csrf 为什么只能伪造 get 请求?其他请求照样可以伪造啊。
至于楼主的问题,我理解了一下,应该就是楼主希望能够跨域读取到 cookie,那你应该去了解一下相关的跨域读取技术,比如说 postMessage ()方法。 |
4
comwrg 2019-09-01 09:19:39 +08:00
1. 设置 Access-Control-Allow-Origin 为你的前端域名
2. 简单请求不做资源更改 3. 检查 Origin, Referer |
5
ochatokori 2019-09-01 09:37:48 +08:00 via Android
|
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>
|
7
whoami9894 2019-09-01 10:36:10 +08:00 via Android
#1 说的,既然请求后端域名不带 cookie 那也没必要防范 CSRF 了
然而真正情况是,你会使用某些跨域方法来请求后端接口并且肯定需要带上 Cookie,比如 CORS 的 access-control-allow-credentials,所以最终用 token 防范 CSRF 的话还是和文档里说的是同一种情形 |
8
jugelizi 2019-09-01 10:36:24 +08:00 1
即便这样 登录的时候返回 csrf 的 token 即可啊 前端自己存储 然后自己加到 header
|
9
ochatokori 2019-09-01 12:59:58 +08:00 via Android
@oott123 #6 对哦,我都忘记普通的表单是会跳到 action 的,脑筋转死了嘻嘻
|
10
jybox 2019-09-02 11:27:01 +08:00
@ochatokori 可以看下「简单请求」,都是有 CSRF 的风险的 developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS#%E7%AE%80%E5%8D%95%E8%AF%B7%E6%B1%82
|