V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
petelin
V2EX  ›  问与答

对付 crsf 的关键在于让恶意网站无法伪造信息,那么为什么要那么复杂?

  •  
  •   petelin · 2016-10-28 16:17:23 +08:00 · 2933 次点击
    这是一个创建于 2955 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我知道现在的避免 crsf 做法,也看过 django 的中间件的实现.

    但是,恶意网站所能做的事情很少啊,比如他是不能任意添加 HEAD 的,这是 cors 的限制,简单请求你只能自定义那几个方法,复杂请求更安全了,恶意网站都发不了请求. (这句话对吗?)

    所以我们可以直接在后端验证一下有没有自定的 header, 对应的值对不对,注意这个是静态的 header,整个网站都一样的.

    但是没人这么做过,应该是不对,所以请问各位那里错了?

    第 1 条附言  ·  2016-10-28 17:03:57 +08:00
    CRSF 全称 Cross Site Request Forgery ,跨站请求伪造。用我话说恶意网站 B 在用户不知情的情况下操作了网站 A 的用户资源状态.
    所以设计到如何规避恶意网站 B, 是在浏览器的框架里怎么钻漏洞,不是防爬虫好不.
    第 2 条附言  ·  2016-10-28 18:18:11 +08:00

    我找到老外的讨论了,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

    http://security.stackexchange.com/questions/23371/csrf-protection-with-custom-headers-and-without-validating-token

    32 条回复    2016-10-29 05:52:48 +08:00
    airyland
        1
    airyland  
       2016-10-28 16:32:43 +08:00
    后端直接发啊,哪有 cors 限制。。
    murmur
        2
    murmur  
       2016-10-28 16:37:56 +08:00
    最简单对付 crsf 不就一个 token 的事么 有那么复杂么 何况防重复提交的表单不考虑 crsf 也都加了 token 吧
    jugelizi
        3
    jugelizi  
       2016-10-28 16:38:41 +08:00
    cors 是浏览器的功能
    谁知道万一浏览器厂商出个 bug 可以绕过呢
    还是 flash 可没限制自定义 header
    mdzz
        4
    mdzz  
       2016-10-28 16:48:25 +08:00
    用户输入是不可信的。—— 佚名(到底谁说的
    larry618
        5
    larry618  
       2016-10-28 16:53:05 +08:00 via Android   ❤️ 1
    @mdzz 佚名 ==> 沃 兹基硕德
    petelin
        6
    petelin  
    OP
       2016-10-28 16:54:24 +08:00
    @murmur token 是要生成的,我的问题是我们不需要生成,直接跟前端定义好一个就行.一直用一个就好.
    petelin
        7
    petelin  
    OP
       2016-10-28 16:55:55 +08:00
    @airyland 有后端无视你任何防御手段.
    ryd994
        8
    ryd994  
       2016-10-28 16:56:21 +08:00
    @petelin WTF ,那叫什么 token ?
    人家抓一下你源代码全都出来了
    ryd994
        9
    ryd994  
       2016-10-28 16:58:43 +08:00
    @petelin 就算直接发请求也绕不过一次性 token 啊,用过就失效了,因为是在服务器上限制的
    而 cors 用 curl 就能跳过
    petelin
        10
    petelin  
    OP
       2016-10-28 16:59:21 +08:00
    @jugelizi 这个解释比较合理...那要这么说的话,我们把 token 放在 cookie 里也不保险,万一浏览器有问题,恶意网站能拿到 cookie 里的值然后放在 post 中呢 /
    shiji
        11
    shiji  
       2016-10-28 17:06:08 +08:00
    难道不是 CSRF 么?楼主把二楼都给带顺拐了。
    murmur
        12
    murmur  
       2016-10-28 17:07:34 +08:00
    @petelin 所以 cookie 放在前台页面生成好不跟 cookie 啊
    glasslion
        13
    glasslion  
       2016-10-28 17:16:21 +08:00
    crsf 主要防的的劫持 form 提交(xss), 而 表单提交是 无法设置 http header 的。

    cors 和 csrf 有毛线关系
    falcon05
        14
    falcon05  
       2016-10-28 17:24:33 +08:00 via iPhone
    csrf 处理 ajax 请求一般就是在 head 附一个特殊字段
    mdzz
        15
    mdzz  
       2016-10-28 17:25:16 +08:00   ❤️ 1
    CRSF 全称 Cross Site Request Forgery ,跨站请求伪造。用我话说恶意网站 B 站在用户不知情的情况下操作了 A 站的用户资源状态。 —— 沃·兹基硕德

    (该去看眼科了
    falcon05
        16
    falcon05  
       2016-10-28 17:27:08 +08:00 via iPhone
    @falcon05 但 header 的这个字段是动态的,或者说有过期时间
    gamexg
        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
    petelin
        18
    petelin  
    OP
       2016-10-28 17:47:09 +08:00
    @falcon05 所以我的问题是他是静态的也可啊,非要费劲生成一个动态干嘛?
    petelin
        19
    petelin  
    OP
       2016-10-28 17:51:35 +08:00
    @gamexg 有道理,直接添加静态变化字段是很好的解决方案.
    但是如果我提供的全是 api 呢,django 给出的方案是 cookie+post+token, 而我觉得直接在 ajax 提交的时候设置特殊 *静态 * HEAD, 服务器校验就好,即解决了问题,又不复杂.
    Mutoo
        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 由服务端生成,并设置有效期。
    Mutoo
        21
    Mutoo  
       2016-10-28 18:01:38 +08:00
    @falcon05 一针见血, GET 请求也是 Request Header 的一部分。
    gamexg
        22
    gamexg  
       2016-10-28 18:02:19 +08:00
    falcon05
        23
    falcon05  
       2016-10-28 18:04:59 +08:00 via iPhone
    @Mutoo 如果按规范的话, GET 请求不会改变服务器状态,所以 csrf 并不需要对 get 请求处理。但是很多网站并没有按套路出牌……
    falcon05
        24
    falcon05  
       2016-10-28 18:08:30 +08:00 via iPhone
    @petelin 习惯吧,因为觉得 token 跟 cookie 有关系,而 cookie 是有过期时间的,所以习惯性地也把 header 的 token 搞一个过期时间,我记得 CI 框架就是有这个配置,其实我觉得静态 header 的 token 也未尝不可
    Mutoo
        25
    Mutoo  
       2016-10-28 18:10:48 +08:00
    @falcon05 确实,把 token 放在 X-CSRF-TOKEN 里更合理些。

    静态的 header 并不安全。如果黑客对恶意网站有完整的控制权,可以直接伪造完整的 request 。一样可以 CSRF
    billlee
        26
    billlee  
       2016-10-28 19:29:37 +08:00   ❤️ 1
    自定义 header 肯定能防 csrf, 但是,但那毕竟要用 ajax 才能实现,如果不用 javascript, 就只能用 csrf token 了。
    20150517
        27
    20150517  
       2016-10-28 19:38:20 +08:00
    @Mutoo GET 是没有 X_REQUESTED_WITH 的,所以你说的 img 没法实现
    20150517
        28
    20150517  
       2016-10-28 19:41:45 +08:00
    @Mutoo 另外如果你对恶意网站完整控制权,你发的 request 只是你网站发的,这又怎么样?没看懂
    oott123
        29
    oott123  
       2016-10-28 21:10:11 +08:00
    🌚仅对 10 楼:如果恶意网站能拿到你的 cookie ,那它也用不着去 csrf 你了。
    cmxz
        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
    petelin
        31
    petelin  
    OP
       2016-10-28 22:13:53 +08:00 via Android
    @cmxz 大神总是出来的晚,学习
    msg7086
        32
    msg7086  
       2016-10-29 05:52:48 +08:00
    没记错的话 CSRF 是早于 CORS 出现的。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2679 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 07:24 · PVG 15:24 · LAX 23:24 · JFK 02:24
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.