是什么让跨域ajax不安全?

时间:2012-02-06 23:44:59

标签: ajax security cross-domain

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

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

就此而言,看起来好像使用JSONP http://en.wikipedia.org/wiki/JSONP,您可以执行跨域ajax允许您执行的所有操作。

有人可以启发我吗?

5 个答案:

答案 0 :(得分:12)

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

想象一下,我已登录Gmail,并且该Gmail有一个JSON资源http://mail.google.com/information-about-current-user.js,其中包含有关已登录用户的信息。此资源可能是由Gmail用户界面使用,但是,如果不是针对同源策略,我访问过的任何网站以及怀疑我可能是Gmail用户的网站都可以运行AJAX请求来获取该资源资源 as me ,并检索有关我的信息,而Gmail无法做很多事情。

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

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

答案 1 :(得分:2)

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

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

  

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

     

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

编辑:

让XHR跨域工作的问题在于许多Web服务都会公开ambient authority。通常,该权限仅适用于来自同一来源的代码。

这意味着信任网站的用户信任该网站的所有代码及其私人数据。用户信任他们发送数据的服务器,以及由该服务器提供的页面加载的任何代码。当网站背后的人及其加载的图书馆值得信赖时,用户的信任就得到了充分的信任。

如果XHR工作于跨域,并且携带了cookie,则可以使用环境权限来向可以向用户提供代码的任何人进行编码。用户之前做出的信任决定可能不再适当。

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

答案 2 :(得分:1)

JS->Server(PHP)->API的模式使得它成为可能而且不仅是最好的,而且是理智的基本实践 - 检查在通过服务器时获得的内容。除此之外,服务器上的局部解析器(也称为DNS蠕虫)等等的可能性要小于某些随机客户端。

至于JSONP:这不是拐杖,而是拐杖。恕我直言,它可以被看作是对HTML / JS组合错误的利用,在不破坏现有代码的情况下无法删除。其他人可能会认为不同。

虽然JSONP 允许你在不好的广阔世界中从somwhere无意义地执行代码,但没有人强制你这样做。 JSONP的Sane实现总是使用某种散列等来验证该代码的提供者是否值得信任。其他人可能会认为不同。

答案 3 :(得分:0)

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

另一方面,JSONP允许您以JSON格式获取数据,因为您提供了传递数据所需的回调,因此它为您提供了控制措施,因为除非回调函数,否则浏览器不会执行数据做和执行或尝试执行它。数据将采用JSON格式,然后您可以随意执行,但不会执行,因此更安全,因此允许使用。

答案 4 :(得分:0)

original XHR从未设计为允许跨源请求。原因是CSRF attacks主要知道一个有形的安全漏洞。

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

现在可以轻松伪造这样的请求:从简单的GET请求开始,使用<img src="…">通过使用表单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的攻击。<​​/ p>

所以从安全的角度来看结论:

  • XHR需要请求JSON资源才能在JavaScript中获取响应
  • XHR2 / CORS需要对JSON资源进行跨源请求才能在JavaScript中获取响应
  • JSONP是一种使用XHR来绕过跨源请求的解决方法

但是:

  • 伪造请求很容易搞笑,虽然伪造有效和合法的请求更难(但通常也很容易)
  • CSRF攻击是一个不可低估的威胁,因此请学习如何protect against CSRF