首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
宝塔
V2EX  ›  程序员

这种破解 CSRF 防御的方法是否可行?

  •  
  •   xvrzhao · 2018-02-05 00:44:48 +08:00 · 4405 次点击
    这是一个创建于 655 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我们首先统一一下口径: 站点 A:被攻击的网站 站点 B:伪造请求的网站

    一般网站的防御方法是: 判断请求中的 token 和 cookie 中的 token 是否相同,相同则表示请求发起者和会话用户是同一个人。

    这种防御方法可行的原因是: 站点 B 无法获取到站点 A 的 cookie,所以无法在请求中添加 token。

    但,我们假设站点 B 知道站点 A 的某个页面表单里有隐藏的 token 字段,那么,站点 B 在自己的页面中写一个隐藏的 iframe 去请求这个页面。(这里有一个问题,iframe 会创建新的会话吗?但不管会不会,都有如下可能)

    1. iframe 不会生成新的会话。那么对于用户而言,假设用户在访问站点 A 后没有关闭站点又去访问了站点 B,那么站点 B 中的 iframe 和站点 A 属于同一个会话,也就是说他们的 token 相同。这个时候站点 B 通过预先写好的脚本去获取到 iframe 中的 token,然后在伪造的请求中加入这个 token,能否成功?

    2. iframe 会生成新的会话。那也就是说站点 B 的 iframe 中的 token 和站点 A 的 token 值是不相同的,但是可以使用以下方法去伪造请求:站点 B 不是直接在页面中添加伪造请求,而是在 iframe 里去添加伪造请求,由于 iframe 中是站点 A 的会话,所以请求会带着站点 A 的 cookie 一起发出去,由于 iframe 和站点 A 共用一套 cookie (因为同域),所以就成功盗用了用户的身份。这种方法可行吗?

    第 1 条附言  ·  2018-02-05 08:38:44 +08:00
    经过验证,iframe 并不会产生新的会话,而是会沿用未关闭的站点 A 的会话。

    也就是说,iframe 中的 token 已经可见,关键在于脚本是否能够获取到。
    第 2 条附言  ·  2018-02-05 09:14:39 +08:00

    看来我描述的让有些v友产生了误解,我修改下上述验证:

    经过验证,iframe 并不会产生新的会话,而是会沿用未关闭的站点 A 的会话。

    也就是说,iframe 中 表单的 token 字段 已经可见,关键在于脚本是否能够获取到。

    第 3 条附言  ·  2018-02-05 09:37:58 +08:00
    不过好像 Chrome 扩展可以拿到 iframe 中的内容,黑客或许可以这么干,当用户访问站点 b 的时候,站点 b 要求安装扩展,该扩展拿到 token 上传服务端,然后 websocket 将 token 发给站点 b,并告知站点 b 可以去伪造请求了。
    20 回复  |  直到 2018-02-06 08:17:58 +08:00
        1
    40huo   2018-02-05 00:51:06 +08:00 via Android
    你说的这个应该在 xss 和同源策略的范围讨论,和 csrf 已经关系不大了
        2
    fy   2018-02-05 00:53:24 +08:00
    > 这里有一个问题,iframe 会创建新的会话吗?
    会,但是并不能跨域进行对 iframe 的任何操作。所以取不到 token。
        3
    lxy   2018-02-05 01:06:26 +08:00
    因为同源策略,所以你无法获取 token
    >Scripts trying to access a frame's content are subject to the same-origin policy, and cannot access most of the properties in the other window object if it was loaded from a different domain.
    https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe
        4
    yyfearth   2018-02-05 04:03:58 +08:00 via iPhone
    这个 首先你就没办法访问跨域的 iframe 所以你说的方法从根本上就不可能
        5
    alvinbone88   2018-02-05 08:18:00 +08:00   ♥ 1
    一般带有 CSRF 防御的页面通常会在 HTTP 的响应头里加一个 X-Frame-Options 来阻止页面在 iframe 中加载,所以把页面嵌在 iframe 里根本不可能,得到的结果就是一片空白
    另外提醒一下,在页面中加<meta http-equiv="X-Frame-Options" content="deny">会被部分浏览器忽略掉(比如 IE )
        6
    zjsxwc   2018-02-05 08:26:46 +08:00
    ```
    一般网站的防御方法是: 判断请求中的 token 和 cookie 中的 token 是否相同,相同则表示请求发起者和会话用户是同一个人。
    ```

    楼主你一开始就搞错了吧,不是判断 cookie 的 token 而是服务器端 session 里的 token
        8
    MeteorCat   2018-02-05 08:57:21 +08:00 via Android   ♥ 1
    首先,其实就目前来说所有语言的 Web 现代化框架都带有对这种方法的屏蔽,基本上都是内部页面表单会生成一个 hidden 的字段,确保这次提交是请求服务之后返回下来表单(虽然很多人都不用这个,因为基本上除非你直接网页就被挂马,否则内嵌而已 iframe 来提交表单基本上可以认定为小概率事件不做考虑);其次就是如何内嵌 iframe 到页面做请求?楼主有真实案例?纸上得来终觉浅,绝知此事要躬行
        9
    oott123   2018-02-05 09:20:23 +08:00 via Android   ♥ 1
    可见只是你可见,对脚本不可见,如果脚本都可见,那就是 xss 了…
    另外通过 iframe 攻击的有跨站框架攻击( xfs ),也有对应的防御方法。
        10
    RadishWind   2018-02-05 09:38:04 +08:00
    有同源策略的 不然太不安全了
        11
    ai277014717   2018-02-05 10:04:59 +08:00
    不错,昨天还在看 express 官方中间件 csrf 的代码,确实只要保证 token 喝 cookie 中的 token 一致就可以了。
    就是想办法拿到 cookie 就可以了
        12
    binux   2018-02-05 10:22:39 +08:00
    你都用上插件了,还费那个劲搞什么 iframe 啊,A 的 cookie 你不是想读就读,想写就写吗。
    说白了就是,想得太多,多读点书。
        13
    liuguang   2018-02-05 10:22:41 +08:00
    你拿不到别人的 cookie 的,自然也拿不到 Token,你觉得伪造一个 Token 会有效吗、、、
        14
    LeungJZ   2018-02-05 10:36:16 +08:00
    楼主不是前端吧。
    怎么可能可以获取一个跨域 iframe 里面的东西?
        15
    DOLLOR   2018-02-05 11:30:18 +08:00
    1、iframe 也必须遵循同源策略的,B 是无法获取 iframe 里 A 的 cookie,浏览器会简单粗暴地拒绝你的脚本。
    2、如果用上扩展了,都可以监听用户的键盘、鼠标操作了,都可以窜改页面了,比绕个弯子搞 iframe 的更好的方法多了去了。
        16
    johnnie502   2018-02-05 12:50:38 +08:00
    扩展也是有作用域的,你搞个作用域是所有网站的,还不是随便什么域都可以看。这种东西不是那么容易被破的,总想搞个大新闻
        17
    virusdefender   2018-02-05 13:34:32 +08:00
    思而不学则殆 / 纸上得来终觉浅

    楼主不测试就发帖子啊
        18
    wanguorui123   2018-02-05 17:08:34 +08:00
    除非浏览器允许跨域访问或者浏览器漏洞,否则就不可能
        19
    pynix   2018-02-05 21:34:25 +08:00
    @binux 😂
        20
    Telegram   2018-02-06 08:17:58 +08:00 via iPhone
    跨域知道不? A 站没设置信任 B,B 根本就取不到 A 的数据,只要是个正常的浏览器,都不让你读。
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1047 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 25ms · UTC 19:09 · PVG 03:09 · LAX 11:09 · JFK 14:09
    ♥ Do have faith in what you're doing.