我不知道这会导致什么类型的漏洞。
当我需要从API访问数据时,我必须使用ajax在自己的服务器上请求一个PHP文件,而该PHP文件访问API。是什么比简单地允许我直接使用ajax访问API更安全?
就这一点而言,它看起来像是在使用JSONPhttp://en.wikipedia.org/wiki/JSONP您可以做跨域ajax允许您做的所有事情。
有人能启发我吗?
我认为您误解了同源策略试图解决的问题。
想象一下,我登录了Gmail,而Gmail有一个JSON资源http://mail.google.com/information-about-current-user.js,其中包含有关登录用户的信息。这个资源可能是由Gmail用户界面使用的,但如果不是出于同源政策,我访问的任何网站,如果怀疑我可能是Gmail用户,都可以运行AJAX请求,以获取该资源作为我,并检索有关我的信息,而Gmail对此无能为力。
因此,同源策略不是保护您的PHP页面不受第三方网站的影响;这并不是为了保护从第三方网站访问你的PHP页面的人;相反,它是为了保护访问您的PHP页面的人,以及他们有特殊访问权限的任何第三方网站,从您的PHP页。("特殊访问"可能是因为cookie、HTTP AUTH或IP地址白名单,或者只是在正确的网络上,也可能是有人在美国国家安全局工作并正在访问您的网站,这并不意味着您应该能够从美国国家安全局内部页面触发数据转储。)
JSONP以一种安全的方式绕过了这一点,引入了一个不同的限制:只有当资源是JSONP时,它才有效。因此,如果Gmail希望给定的JSON资源可供第三方使用,它可以支持该资源的JSONP,但如果它只希望该资源可由自己的用户界面使用,它只能支持纯JSON。
许多web服务并不是为了抵御XSRF而构建的,因此,如果一个网站可以通过携带跨域cookie的请求以编程方式加载用户数据,那么任何能够运行javascript的人都可以窃取用户数据。
CORS是XHR的一种计划中的安全替代方案,它通过默认不携带凭据来解决问题。CORS规范解释了这个问题:
用户代理通常对网络请求应用同源限制。这些限制阻止从一个源运行的客户端Web应用程序获取从另一个源检索的数据,还限制了可以自动向与运行的应用程序的源不同的目的地启动的不安全HTTP请求。
在遵循此模式的用户代理中,网络请求通常使用环境身份验证和会话管理信息,包括HTTP身份验证和cookie信息。
编辑:
让XHR跨域工作的问题是,许多web服务暴露了环境权限。通常,该权限仅适用于来自同一来源的代码。
这意味着,信任某个网站的用户将其私人数据信任该网站的所有代码。用户信任他们将数据发送到的服务器,以及由该服务器提供服务的页面加载的任何代码。当一个网站及其加载的库背后的人是可信的时,用户的信任就处于良好的位置。
如果XHR跨源工作,并携带cookie,那么环境权限将可用于向任何可以向用户提供代码的人进行代码编写。用户先前做出的信任决策可能不再处于有利位置。
CORS不会继承这些问题,因为现有服务不会向CORS公开环境权限。
JS->Server(PHP)->API
的模式使它成为可能,不仅是最好的,而且是在它通过服务器时对您得到的内容进行健全性检查的基本实践。除此之外,像中毒的本地解析器(又名DNS蠕虫)等在服务器上的可能性要比在一些随机客户端上小得多。
至于JSONP:这不是一根拐杖,而是一根拐杖。IMHO,它可以被视为针对HTML/JS组合的一个错误功能的攻击,如果不破坏现有代码,就无法删除该功能。其他人可能对此持不同看法。
虽然JSONP允许在糟糕的世界中无条件地执行代码,但没有人强迫执行。JSONP的许多实现都使用某种哈希等来验证该代码的提供者是否可信。其他人可能会有不同的想法。
使用跨站点脚本,您将拥有一个能够从任何地方提取数据的网页,然后能够在与页面上的其他数据相同的上下文中运行,并且理论上可以访问cookie和其他安全信息,而您也不希望访问这些信息。在这方面,跨站点脚本编写是非常不安全的,因为你可以访问任何页面,如果允许,该页面上的脚本可以从任何地方加载数据,然后开始执行错误的代码,因此这是不允许的。
另一方面,JSONP允许您以JSON格式获取数据,因为您提供了将数据传递到的必要回调,因此它为您提供了控制措施,即除非回调函数执行或尝试执行数据,否则浏览器不会执行数据。数据将采用JSON格式,然后您可以随心所欲地使用它,然而它不会被执行,因此它更安全,因此它被允许。
最初的XHR从未被设计为允许跨来源请求。原因是一个有形的安全漏洞,主要由CSRF攻击所知。
在这种攻击场景中,第三方网站可以强制受害者的用户代理向原始网站发送伪造但有效和合法的请求。从原始服务器的角度来看,这种伪造的请求与该用户由原始服务器的网页发起的其他请求是不可区分的。原因是,实际上是用户代理发送这些请求,而且它还会自动包括任何凭据,如cookie、HTTP身份验证,甚至客户端SSL证书。
现在,这样的请求可以很容易地伪造:从使用<img src="…">
的简单GET请求开始,到使用表单并自动提交的POST请求。只要可以预测如何伪造这样的有效请求,这就有效。
但这并不是禁止XHR跨来源请求的主要原因。因为,如上所示,即使没有XHR,甚至没有JavaScript,也有伪造请求的方法。不,XHR不允许跨来源请求的主要原因是,响应将发送到第三方网页中的JavaScript。因此,不仅可以发送跨来源请求,还可以接收包含敏感信息的响应,然后JavaScript可以访问这些信息。
这就是为什么原始XHR规范不允许跨源请求的原因。但随着技术的进步,支持跨来源请求的请求也越来越合理。这就是为什么最初的XHR规范被扩展到XHR级别2(XHR和XHR级别2中现在合并了),其中的主要扩展是支持指定为CORS的特定需求下的跨源请求。现在,服务器可以检查请求的来源,还可以限制允许的来源集以及允许的HTTP方法和标头字段集。
现在来看JSONP:要用JavaScript获取请求的JSON响应并能够处理它,它要么需要是同源请求,要么在跨源请求的情况下,您的服务器和用户代理需要支持CORS(后者仅受现代浏览器支持)。但为了能够与任何浏览器一起工作,JSONP被发明了,它只是一个以JSON为参数的有效JavaScript函数调用,可以通过<script>
作为外部JavaScript加载,类似于<img>
,不限于同源请求。但是,与任何其他请求一样,JSONP请求也容易受到CSRF的攻击。
因此,从安全角度来总结它:
- XHR需要请求JSON资源以获得JavaScript中的响应
- XHR2/CORS需要对JSON资源进行跨源请求,以获得JavaScript中的响应
- JSONP是使用XHR规避跨源请求的一种变通方法
但也包括:
- 伪造请求很容易,尽管伪造有效和合法的请求更难(但通常也很容易)
- CSRF攻击是一种不容低估的威胁,因此请学习如何防范CSRF