【问题标题】:What makes cross domain ajax insecure?是什么让跨域 ajax 不安全?
【发布时间】:2012-02-28 10:55:02
【问题描述】:

我不确定我是否了解这会导致哪些类型的漏洞。

当我需要从 API 访问数据时,我必须使用 ajax 在我自己的服务器上请求 PHP 文件,并且该 PHP 文件会访问 API。是什么让这比让我直接使用 ajax 直接访问 API 更安全?

就此而言,看起来使用 JSONP http://en.wikipedia.org/wiki/JSONP 您可以完成跨域 ajax 可以让您做的所有事情。

有人可以启发我吗?

【问题讨论】:

标签: ajax security cross-domain


【解决方案1】:

使用跨站点脚本,您将拥有一个能够从任何地方提取数据的网页,然后能够在与页面上的其他数据相同的上下文中运行,并且理论上可以访问 cookie 和其他您也不希望获得访问权限的安全信息。跨站点脚本在这方面是非常不安全的,因为您可以转到任何页面,并且如果允许该页面上的脚本可以从任何地方加载数据,然后开始执行错误代码,因此它是不允许的。

另一方面,JSONP 允许您以 JSON 格式获取数据,因为您提供了数据传递到的必要回调,因此它为您提供了控制措施,除非回调函数,否则浏览器不会执行数据执行并执行或尝试执行它。数据将采用 JSON 格式,然后您可以随心所欲地执行任何操作,但它不会被执行,因此它更安全,因此是允许的。

【讨论】:

  • 但是网站已经可以从任何地方提取数据,并在当前页面的上下文中运行它。我可以放 ,浏览器会很高兴地在完全许可的情况下运行它。这就是我感到困惑的地方。
  • 但这将无法从其他网站访问 javascript,因此跨站点脚本背后的安全性。
  • 我对 JSONP 的印象与您在阅读 Wikipedia JSONP 文章时的印象截然不同——JSONP 请求返回的内容明确不是 JSON,而是任意的 JavaScript 通常除了函数定义或执行之外,还包括 JSON 格式的数据。
  • 返回 JSON,否则为什么会是带填充的 JSON。 JSON 封装在您要调用的函数中,并作为参数传递。
  • @darren102 - 你是对的。我们“应该”从 JSONP 请求返回的数据是带填充的 JSON。但是,没有什么可以阻止服务器使用任意 JavaScript 代码进行响应 - 然后将在全局上下文中执行。
【解决方案2】:

许多网络服务并不是为了抵抗XSRF而构建的,所以如果一个网站可以通过一个携带跨域cookie的请求以编程方式加载用户数据,仅仅因为用户访问了该网站,任何有能力的人运行javascript可以窃取用户数据。

CORS 是一个计划中的 XHR 安全替代方案,它通过not carrying credentials by default 解决了该问题。 CORS 规范解释了这个问题:

用户代理通常对网络请求应用同源限制。这些限制阻止从一个源运行的客户端 Web 应用程序获取从另一个源检索的数据,并且还限制了可以自动向与运行应用程序的源不同的目的地发起的不安全 HTTP 请求。

在遵循此模式的用户代理中,网络请求通常使用环境身份验证和会话管理信息,包括 HTTP 身份验证和 cookie 信息。

编辑:

让 XHR 跨域工作的问题是许多 Web 服务暴露了ambient authority。通常,该权限仅适用于来自同一来源的代码。

这意味着信任网站的用户信任该网站的所有代码及其私人数据。用户信任他们将数据发送到的服务器,以及由该服务器提供的页面加载的任何代码。当网站背后的人和它加载的库是值得信赖的时,用户的信任就很好。

如果 XHR 可以跨域工作并携带 cookie,那么任何可以为用户提供代码的人都可以使用该环境权限来编写代码。用户之前做出的信任决定可能不再合适。

CORS 不会继承这些问题,因为现有服务不会向 CORS 公开环境权限。

【讨论】:

  • 如果我错了,请纠正我:如果敏感数据作为对具有正确会话 cookie 的完全有效的 HTTP 请求的响应而被发回,它不一定是 XSRF 漏洞?否则,根据您的定义,基本上每个具有登录系统的网站都容易受到 XSRF 的攻击。
  • 所以你是说用 ajax ping 一个 url 和用 PHP ping 它的区别在于 ajax 的行为就像是用户自己访问该页面,而 PHP 的行为就像它访问该页面时运行 PHP 的服务器是什么?
  • @NiklasB.,我想我同意。问题在于通常只能由同源代码执行的环境权限。 XSRF 是一种滥用环境权限的行为,但还有其他的。
  • 我不明白为什么没有标志来防止从 ajax 开始携带凭据。
  • @Joren,我听到的故事是 XSRF 被许多安全研究人员预测为一个问题,但最初被视为仅具有理论意义的攻击向量而被驳回。如果您有兴趣,cap-talk@mail.eros-os.org 上的人们可能会向您介绍这段历史。
【解决方案3】:

JS->Server(PHP)->API 的模式使得它成为可能,不仅是最好的,而且是必要的实践,可以在通过服务器时对你得到的内容进行健全性检查。除此之外,像平衡的本地解析器(又名 DNS 蠕虫)等在服务器上的可能性要小得多,而不是在某些随机客户端上。

至于 JSONP:这不是拐杖,而是拐杖。恕我直言,它可以被视为针对 HTML/JS 组合的错误功能的利用,如果不破坏现有代码就无法删除。其他人可能对此有不同的看法。

虽然 JSONP 允许您在糟糕的广阔世界中不加思索地执行代码,但没有人强迫您这样做。 JSONP 的健全实现总是使用某种散列等来验证该代码的提供者是否值得信赖。再一次,其他人可能会有不同的想法。

【讨论】:

    【解决方案4】:

    我认为您误解了同源策略试图解决的问题。

    假设我已登录 Gmail,并且 Gmail 有一个 JSON 资源 http://mail.google.com/information-about-current-user.js,其中包含有关已登录用户的信息。该资源可能是供 Gmail 用户界面使用的,但是,如果不是出于同源策略,我访问过的任何网站,并且怀疑我可能是 Gmail 用户,都可以运行 AJAX 请求来获取该资源资源作为我,并检索有关我的信息,而 Gmail 对此无能为力。

    所以同源策略不是为了保护你的PHP页面免受第三方网站的侵害;这并不是为了保护从第三方网站访问您的 PHP 页面的人;相反,它是为了保护访问您的 PHP 页面的人,以及他们有特殊访问权限的任何第三方站点,从您的 PHP 页面。 (“特殊访问”可能是因为 cookie、HTTP AUTH 或 IP 地址白名单,或者只是在正确的网络上——也许有人在 NSA 工作并正在访问您的站点,但这并不意味着您应该能够从 NSA 内部页面触发数据转储。)

    JSONP 通过引入不同的限制以一种安全的方式规避了这一点:它仅在资源是 JSONP 时才有效。因此,如果 Gmail 希望给定的 JSON 资源可供第三方使用,它可以支持该资源的 JSONP,但如果它只希望该资源可由其自己的用户界面使用,它只能支持纯 JSON。

    【讨论】:

    • 这是对问题的一个很好的描述。我的误解是认为问题来自您所在的网站以外的其他网站可以对您做什么。问题实际上是您当前访问的网站可以对您做什么。现在更有意义了。
    【解决方案5】:

    original XHR 从未设计为允许跨域请求。原因是一个明显的安全漏洞,主要由 CSRF attacks 知道。

    在这种攻击场景中,第三方站点可以强制受害者的用户代理向源站点发送伪造但有效且合法的请求。从原始服务器的角度来看,这样的伪造请求与该用户由原始服务器的网页发起的其他请求并不是不可区分的。这样做的原因是因为它实际上是发送这些请求的用户代理,它还会自动包含任何凭据,例如 cookie、HTTP 身份验证,甚至是客户端 SSL 证书。

    现在可以轻松伪造此类请求:从使用 <img src="…"> 的简单 GET 请求开始,到使用表单并自动提交它们的 POST 请求。只要可以预测如何伪造此类有效请求,这种方法就可以工作。

    但这并不是禁止 XHR 跨域请求的主要原因。因为,如上所示,即使没有 XHR 甚至没有 JavaScript,也有一些方法可以伪造请求。不,XHR 不允许跨域请求的主要原因是因为它将是第三方网页中的 JavaScript 响应将被发送到。因此,不仅可以发送跨域请求,还可以接收包含敏感信息的响应,然后 JavaScript 可以访问这些信息。

    这就是为什么最初的 XHR 规范不允许跨域请求。但随着技术的进步,支持跨域请求的合理请求出现了。这就是为什么最初的 XHR 规范被扩展到 XHR level 2(XHR 和 XHR 级别 2 现在合并),其中主要扩展是支持在指定为 CORS 的特定要求下的跨域请求。现在,服务器可以检查请求的来源,还可以限制允许的来源集以及允许的 HTTP 方法和标头字段集。

    现在到 JSONP:要在 JavaScript 中获取请求的 JSON 响应并能够处理它,它需要是同源请求,或者如果是跨源请求,您的服务器和用户代理需要支持 CORS(后者仅受现代浏览器支持)。但是为了能够与任何浏览器一起工作,发明了 JSONP,它只是一个有效的 JavaScript 函数调用,以 JSON 作为参数,可以通过<script> 作为外部 JavaScript 加载,类似于<img>,不受限制同源请求。但与任何其他请求一样,JSONP 请求也容易受到 CSRF 的攻击。

    所以从安全的角度来总结一下:

    • 需要 XHR 才能请求 JSON 资源以在 JavaScript 中获取响应
    • 需要 XHR2/CORS 才能对 JSON 资源发出跨域请求,以便在 JavaScript 中获得响应
    • JSONP 是一种使用 XHR 规避跨域请求的解决方法

    还有:

    • 伪造请求很容易,虽然伪造有效和合法的请求更难(但通常也很容易)
    • CSRF 攻击是一个不容小觑的威胁,所以学习如何protect against CSRF

    【讨论】:

      猜你喜欢
      • 2010-10-02
      • 2011-10-29
      • 2018-03-13
      • 2014-10-27
      • 2015-09-20
      • 1970-01-01
      • 1970-01-01
      • 2019-04-03
      • 1970-01-01
      相关资源
      最近更新 更多