我知道现在的避免 crsf 做法,也看过 django 的中间件的实现.
但是,恶意网站所能做的事情很少啊,比如他是不能任意添加 HEAD 的,这是 cors 的限制,简单请求你只能自定义那几个方法,复杂请求更安全了,恶意网站都发不了请求. (这句话对吗?)
所以我们可以直接在后端验证一下有没有自定的 header, 对应的值对不对,注意这个是静态的 header,整个网站都一样的.
但是没人这么做过,应该是不对,所以请问各位那里错了?
我找到老外的讨论了,stackexchange质量更高一点, sof的相同问题 同 v2, 答题质量就很差.可能大部分人都先入为主了.
我的观点是正确的.不用 token 是可以的,不过不是最佳实践而已,有很多理由来反对我.比如回复里有人提到的 Flash 问题.双重保险嘛.
而且还真有人是真么干的,我没点进去 This is how Jersey 1.9's CsrfProtectionFilter works and it is described in this blog post: http://blog.alutam.com/2011/09/14/jersey-and-cross-site-request-forgery-csrf/.
资源: http://security.stackexchange.com/questions/22903/why-refresh-csrf-token-per-form-request
1
airyland 2016-10-28 16:32:43 +08:00
后端直接发啊,哪有 cors 限制。。
|
2
murmur 2016-10-28 16:37:56 +08:00
最简单对付 crsf 不就一个 token 的事么 有那么复杂么 何况防重复提交的表单不考虑 crsf 也都加了 token 吧
|
3
jugelizi 2016-10-28 16:38:41 +08:00
cors 是浏览器的功能
谁知道万一浏览器厂商出个 bug 可以绕过呢 还是 flash 可没限制自定义 header |
4
mdzz 2016-10-28 16:48:25 +08:00
用户输入是不可信的。—— 佚名(到底谁说的
|
9
ryd994 2016-10-28 16:58:43 +08:00
@petelin 就算直接发请求也绕不过一次性 token 啊,用过就失效了,因为是在服务器上限制的
而 cors 用 curl 就能跳过 |
10
petelin OP @jugelizi 这个解释比较合理...那要这么说的话,我们把 token 放在 cookie 里也不保险,万一浏览器有问题,恶意网站能拿到 cookie 里的值然后放在 post 中呢 /
|
11
shiji 2016-10-28 17:06:08 +08:00
难道不是 CSRF 么?楼主把二楼都给带顺拐了。
|
13
glasslion 2016-10-28 17:16:21 +08:00
crsf 主要防的的劫持 form 提交(xss), 而 表单提交是 无法设置 http header 的。
cors 和 csrf 有毛线关系 |
14
falcon05 2016-10-28 17:24:33 +08:00 via iPhone
csrf 处理 ajax 请求一般就是在 head 附一个特殊字段
|
15
mdzz 2016-10-28 17:25:16 +08:00 1
CRSF 全称 Cross Site Request Forgery ,跨站请求伪造。用我话说恶意网站 B 站在用户不知情的情况下操作了 A 站的用户资源状态。 —— 沃·兹基硕德
(该去看眼科了 |
17
gamexg 2016-10-28 17:41:06 +08:00 1
@glasslion +1
需要考虑哪个方案简单,哪个方案兼容性高。 在表单加一个隐藏字段轻松解决,为什么要自己构建 post 请求并添加 header ? 而且 header 兼容性并不好: https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest/setRequestHeader |
19
petelin OP @gamexg 有道理,直接添加静态变化字段是很好的解决方案.
但是如果我提供的全是 api 呢,django 给出的方案是 cookie+post+token, 而我觉得直接在 ajax 提交的时候设置特殊 *静态 * HEAD, 服务器校验就好,即解决了问题,又不复杂. |
20
Mutoo 2016-10-28 17:56:40 +08:00
“恶意网站 B ” 这个定义就很宽泛的,可以是一个你常去的公共论坛,你根本不会注意,然后某个帖子别人插入了一个 img (大部分论坛都允许的)。但是这个 img 的 url 是目标网站 A 的一个 GET 请求地址。一般人访问这个帖子什么也不会发生,但是如果是目标网站的管理员,并且是登陆状态。那么这个 GET 请求就可能触发相应的功能,达成 CRSF 。这个过程黑客只需要构造一个有效的 GET 请求,其它都不需要做,甚至不需要弄到 cookie 。
防 CRSF 的过程就是让黑客无法构造有效的 GET 请求,例子让 get 请求带上 token ,该 token 由服务端生成,并设置有效期。 |
22
gamexg 2016-10-28 18:02:19 +08:00
|
23
falcon05 2016-10-28 18:04:59 +08:00 via iPhone
@Mutoo 如果按规范的话, GET 请求不会改变服务器状态,所以 csrf 并不需要对 get 请求处理。但是很多网站并没有按套路出牌……
|
24
falcon05 2016-10-28 18:08:30 +08:00 via iPhone
@petelin 习惯吧,因为觉得 token 跟 cookie 有关系,而 cookie 是有过期时间的,所以习惯性地也把 header 的 token 搞一个过期时间,我记得 CI 框架就是有这个配置,其实我觉得静态 header 的 token 也未尝不可
|
25
Mutoo 2016-10-28 18:10:48 +08:00
@falcon05 确实,把 token 放在 X-CSRF-TOKEN 里更合理些。
静态的 header 并不安全。如果黑客对恶意网站有完整的控制权,可以直接伪造完整的 request 。一样可以 CSRF |
26
billlee 2016-10-28 19:29:37 +08:00 1
自定义 header 肯定能防 csrf, 但是,但那毕竟要用 ajax 才能实现,如果不用 javascript, 就只能用 csrf token 了。
|
29
oott123 2016-10-28 21:10:11 +08:00
🌚仅对 10 楼:如果恶意网站能拿到你的 cookie ,那它也用不着去 csrf 你了。
|
30
cmxz 2016-10-28 21:27:42 +08:00 via Android 1
楼主的想法确实没错。
另外 CORS 在发添加自定义 header 的请求前会发送预检请求( options ),如果服务端不对预检请求做正确响应,那么 CORS 的自定义 header 是无法发出的。 flash 的跨域,如果我没有记错的话, 1.域名下的 crossdomain.xml 中别随便授权域 2.本域和 crossdomain.xml 中授权的域下别随便放网上找到 swf 文件 3.本域和 crossdomain.xml 中授权的域下别随便允许上传文件(非 swf 的也不能允许,如果因业务必须允许,那需要做一些其他的操作,就不详述了) 做好以上 3 点,应该就 ok 了 ps :从回帖看 v2 上好多人都没完全理解 csrf |
32
msg7086 2016-10-29 05:52:48 +08:00
没记错的话 CSRF 是早于 CORS 出现的。
|