V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
petelin
V2EX  ›  问与答

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

  •  
  •   petelin · Oct 28, 2016 · 3506 views
    This topic created in 3474 days ago, the information mentioned may be changed or developed.

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

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

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

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

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

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

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

    (该去看眼科了
    GG668v26Fd55CP5W
        16
    GG668v26Fd55CP5W  
       Oct 28, 2016 via iPhone
    @falcon05 但 header 的这个字段是动态的,或者说有过期时间
    gamexg
        17
    gamexg  
       Oct 28, 2016   ❤️ 1
    @glasslion +1
    需要考虑哪个方案简单,哪个方案兼容性高。
    在表单加一个隐藏字段轻松解决,为什么要自己构建 post 请求并添加 header ?
    而且 header 兼容性并不好:
    https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest/setRequestHeader
    petelin
        18
    petelin  
    OP
       Oct 28, 2016
    @falcon05 所以我的问题是他是静态的也可啊,非要费劲生成一个动态干嘛?
    petelin
        19
    petelin  
    OP
       Oct 28, 2016
    @gamexg 有道理,直接添加静态变化字段是很好的解决方案.
    但是如果我提供的全是 api 呢,django 给出的方案是 cookie+post+token, 而我觉得直接在 ajax 提交的时候设置特殊 *静态 * HEAD, 服务器校验就好,即解决了问题,又不复杂.
    Mutoo
        20
    Mutoo  
       Oct 28, 2016
    “恶意网站 B ” 这个定义就很宽泛的,可以是一个你常去的公共论坛,你根本不会注意,然后某个帖子别人插入了一个 img (大部分论坛都允许的)。但是这个 img 的 url 是目标网站 A 的一个 GET 请求地址。一般人访问这个帖子什么也不会发生,但是如果是目标网站的管理员,并且是登陆状态。那么这个 GET 请求就可能触发相应的功能,达成 CRSF 。这个过程黑客只需要构造一个有效的 GET 请求,其它都不需要做,甚至不需要弄到 cookie 。

    防 CRSF 的过程就是让黑客无法构造有效的 GET 请求,例子让 get 请求带上 token ,该 token 由服务端生成,并设置有效期。
    Mutoo
        21
    Mutoo  
       Oct 28, 2016
    @falcon05 一针见血, GET 请求也是 Request Header 的一部分。
    gamexg
        22
    gamexg  
       Oct 28, 2016
    GG668v26Fd55CP5W
        23
    GG668v26Fd55CP5W  
       Oct 28, 2016 via iPhone
    @Mutoo 如果按规范的话, GET 请求不会改变服务器状态,所以 csrf 并不需要对 get 请求处理。但是很多网站并没有按套路出牌……
    GG668v26Fd55CP5W
        24
    GG668v26Fd55CP5W  
       Oct 28, 2016 via iPhone
    @petelin 习惯吧,因为觉得 token 跟 cookie 有关系,而 cookie 是有过期时间的,所以习惯性地也把 header 的 token 搞一个过期时间,我记得 CI 框架就是有这个配置,其实我觉得静态 header 的 token 也未尝不可
    Mutoo
        25
    Mutoo  
       Oct 28, 2016
    @falcon05 确实,把 token 放在 X-CSRF-TOKEN 里更合理些。

    静态的 header 并不安全。如果黑客对恶意网站有完整的控制权,可以直接伪造完整的 request 。一样可以 CSRF
    billlee
        26
    billlee  
       Oct 28, 2016   ❤️ 1
    自定义 header 肯定能防 csrf, 但是,但那毕竟要用 ajax 才能实现,如果不用 javascript, 就只能用 csrf token 了。
    20150517
        27
    20150517  
       Oct 28, 2016
    @Mutoo GET 是没有 X_REQUESTED_WITH 的,所以你说的 img 没法实现
    20150517
        28
    20150517  
       Oct 28, 2016
    @Mutoo 另外如果你对恶意网站完整控制权,你发的 request 只是你网站发的,这又怎么样?没看懂
    oott123
        29
    oott123  
       Oct 28, 2016
    🌚仅对 10 楼:如果恶意网站能拿到你的 cookie ,那它也用不着去 csrf 你了。
    cmxz
        30
    cmxz  
       Oct 28, 2016 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
       Oct 28, 2016 via Android
    @cmxz 大神总是出来的晚,学习
    msg7086
        32
    msg7086  
       Oct 29, 2016
    没记错的话 CSRF 是早于 CORS 出现的。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   1015 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 63ms · UTC 23:48 · PVG 07:48 · LAX 16:48 · JFK 19:48
    ♥ Do have faith in what you're doing.