八、跨站请求伪造

    跨站请求伪造,或 CSRF 攻击,在恶意网站、电子邮件、即使消息、应用以及其它,使用户的 Web 浏览器执行其它站点上的一些操作,并且用户已经授权或登录了该站点时发生。这通常会在用户不知道操作已经执行的情况下发生。

    CSRF 攻击的影响取决于收到操作的站点。这里是一个例子:

    1. Bob 登录了它的银行账户,执行了一些操作,但是没有登出。
    2. Bob 检查了它的邮箱,并点击了一个陌生站点的链接。
    3. Bob 的银行站点收到了来自陌生(恶意)站点的请求,没有使用 CSRF Token 的情况下处理了转账。

    更有意思的是这个想法,也就是恶意网站的链接可以包含有效的 HTML,,并且并不需要 Bob 点击链接。如果 Bob 的设备(例如浏览器)渲染了这个图片,它会向malicious_site.com发送请求,来完成 CSRF 攻击。

    现在,知道了 CSRF 的危险之后,它们可以以多种方式防范。最流行的方式大概是 CSRF Token,它必须随着潜在的数据修改气你去一起提交(例如 POST 请求)。这里,Web 应用(例如 Bob 的银行)会生成一个两部分的 Token,一个 Bob 会收到,另一个由应用保管。

    当 Bob 试图提交转账请求时,它就需要提交 Token,银行会验证它这一边的 Token。

    现在,对于 CSRF 和 CSRF Token 来说,跨域资源共享似乎越来越普遍了。或者只是我注意到是这样。本质上,CORS 限制了资源,包括 JSON 响应,被外域访问。换句话说,当 CORS 用于保护站点时,你就不能编写 JavaScript 来调用目标应用,读取响应或者进行另一个调用,除非目标站点允许。

    似乎这非常令人混乱,使用 JavaScript,尝试调用HackerOne.com/activity.json,读取响应并进行二次调用。你也会在下面的例子 #3 看到它的重要性,以及潜在的原理。

    最后,重要的是要记住(感谢 Jobert Abma 补充),并不是每个不带有 CSRF Token 的请求都带有 CSRF 问题。一些站点可能执行额外的检查,例如比较 Referer 协议头(虽然可能出错,并且有一些绕过它的案例)。它是一个字段,标识了链接到被请求资源的页面地址。换句话说,如果 POST 调用中的 Referer 并不来源于收到 HTTP 请求的相同站点,站点可能不允许该调用,因此能够完成和验证 CSRF Token 的相同操作。此外,不是每个站点在创建或者定义 Token 时都使用csrf术语。例如,在 Badoo 它使用rt参数,我们下面会讨论。

    难度:低

    URL:https://app.shopify.com/services/partners/api_clients/XXXX/export_installed_users

    报告链接:

    奖金:$500

    描述:

    Shopify 的 API 提供了一个终端,用于导出已安装用户的列表,通过上面给出的 URL。在站点能够调用该终端,并且读取信息的地方存在漏洞,因为 Shopify 在该调用中并没有包含任何 CSRF Token 验证。所以,下面的 HTML 代码可以用于代表任何未知受害者提交表单。

    这里,通过仅仅浏览站点,JavaScript 就会提交表单,它实际上包含 Shopify API 的 GET 请求,使用受害者的浏览器,并提供 Shopify 的 Cookie。

    难度:低

    URL:https://twitter-commerce.shopifyapps.com/auth/twitter/disconnect

    报告链接:https://hackerone.com/reports/111216

    报告日期:2016.1.17

    奖金:$500

    描述:

    Shopify 提供了 Twitter 的继承,来允许店主转推它们的商品。与之相似,也提供了功能来断开推特账户和被连接商店的链接。

    断开 Twitter 账户的 URL 写在了上面。当进行调用时,Shopify 不验证 CSRf Token,这可能会允许恶意人员代表受害者进行 GET 调用,因此断开受害者的商店与 Twitter 的连接。

    在提供这份报告的时候,WeSecureApp 提供了下面的漏洞请求示例 - 要注意下面的img标签的使用,它对漏洞 URL 进行调用:

    难度:中

    URL:https://badoo.com

    报告链接:https://hackerone.com/reports/127703

    报告日期:2016.4.1

    奖金:$852

    描述:

    如果你仔细检查 Badoo ,你会发现,它们通过包含 URL 参数来防御 CSRF,它只有 5 个位数(至少在我写这篇的时候)。虽然我在 Badoo 入驻 HackerOne 的时候就注意到了,我并没有找到利用它的方式,但是zombiehelp54找到了。

    发现rt参数以及其值之后,它也注意到了,参数一户在所有 JSON 响应中都返回。不幸的是,这并没有什么帮助,因为 CORS 保护了 Badoo,攻击者无法读取这些响应,所以它继续挖掘。

    最终,文件https://eu1.badoo.com/worker-scope/chrome-service-worker.js包含了rt值。更好的是,这个文件可以由攻击者任意读取,而不需要受害者做什么,除了浏览这个恶意页面。这里是它提供的代码。

    本质上,当受害者加载此页面时,它会调用 Badoo 的脚本,为用户获取rt参数,之后代表受害者进行调用,这里,它将受害者的账户链接到了攻击者的,本上上完成了账户的控制。

    通常,如果站点执行 POST 请求,Web 表单都统一由应用框架保护,例如 Rails,但是 API 又是另外一个事情。例如, Shopify 使用了 RoR 编写,它对所有表单默认提供了 CSRF 保护(当然也可以关掉)。但是,显而易见,这对于使用框架创建的 API 不一定成立。最后,一定要观察任何通过 GET 请求执行的,修改服务器数据的调用(例如删除操作)。