V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
xvrzhao
V2EX  ›  程序员

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

  •  
  •   xvrzhao · Feb 5, 2018 · 6556 views
    This topic created in 3004 days ago, the information mentioned may be changed or developed.

    我们首先统一一下口径: 站点 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 (因为同域),所以就成功盗用了用户的身份。这种方法可行吗?

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

    也就是说,iframe 中的 token 已经可见,关键在于脚本是否能够获取到。
    Supplement 2  ·  Feb 5, 2018

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

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

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

    Supplement 3  ·  Feb 5, 2018
    不过好像 Chrome 扩展可以拿到 iframe 中的内容,黑客或许可以这么干,当用户访问站点 b 的时候,站点 b 要求安装扩展,该扩展拿到 token 上传服务端,然后 websocket 将 token 发给站点 b,并告知站点 b 可以去伪造请求了。
    20 replies    2018-02-06 08:17:58 +08:00
    40huo
        1
    40huo  
       Feb 5, 2018 via Android
    你说的这个应该在 xss 和同源策略的范围讨论,和 csrf 已经关系不大了
    fy
        2
    fy  
       Feb 5, 2018
    > 这里有一个问题,iframe 会创建新的会话吗?
    会,但是并不能跨域进行对 iframe 的任何操作。所以取不到 token。
    lxy
        3
    lxy  
       Feb 5, 2018
    因为同源策略,所以你无法获取 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
    yyfearth
        4
    yyfearth  
       Feb 5, 2018 via iPhone
    这个 首先你就没办法访问跨域的 iframe 所以你说的方法从根本上就不可能
    alvinbone88
        5
    alvinbone88  
       Feb 5, 2018   ❤️ 1
    一般带有 CSRF 防御的页面通常会在 HTTP 的响应头里加一个 X-Frame-Options 来阻止页面在 iframe 中加载,所以把页面嵌在 iframe 里根本不可能,得到的结果就是一片空白
    另外提醒一下,在页面中加<meta http-equiv="X-Frame-Options" content="deny">会被部分浏览器忽略掉(比如 IE )
    zjsxwc
        6
    zjsxwc  
       Feb 5, 2018
    ```
    一般网站的防御方法是: 判断请求中的 token 和 cookie 中的 token 是否相同,相同则表示请求发起者和会话用户是同一个人。
    ```

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

    楼主不测试就发帖子啊
    wanguorui123
        18
    wanguorui123  
       Feb 5, 2018
    除非浏览器允许跨域访问或者浏览器漏洞,否则就不可能
    pynix
        19
    pynix  
       Feb 5, 2018
    @binux 😂
    Telegram
        20
    Telegram  
       Feb 6, 2018 via iPhone
    跨域知道不? A 站没设置信任 B,B 根本就取不到 A 的数据,只要是个正常的浏览器,都不让你读。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   1469 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 106ms · UTC 17:06 · PVG 01:06 · LAX 10:06 · JFK 13:06
    ♥ Do have faith in what you're doing.