跨域JSONP通信有哪些风险?
在我们的 Web 应用程序中,我们遇到了这样的情况:我们需要从我们完全控制的一个域到我们完全控制的另一个域进行跨域 AJAX 调用。我一直在寻找最佳解决方案,想到的两个是本地文件代理(使用 php::fopen 的本地文件)或 jquery/JSONP。
当我在网上查找时,我看到人们经常谈论使用 JSONP 是多么危险,因为有人可以用它注入恶意数据。困境在于,大多数反对它的论点似乎都站不住脚,所以我来这里是为了向 Stack 寻求澄清。
跨域 JSONP 会打开哪些特定的攻击向量?
根据我的理解,JSONP 的唯一向量与通过包含
因为无论是服务器端代理、 标记还是 ajax/JSONP,风险在于我将其他人的内容放在我的页面上,他们可能会开始占用用户会话如果他们觉得有义务(在某种程度上,这正是谷歌分析通过脚本标签所做的)。
我在网上听到的许多向量都取决于对用户提交的表格和数据的不正确验证。例如,JSONP用于拉取一些文件,该文件将数据放入表单中,然后提交表单以进行数据库插入。如果来自该表单的数据是可信的,因为它来自被认为是安全的源(JSONP 数据),并且在未经验证的情况下放入,那么这又不是 JSONP 的错误,而是未正确验证的用户输入。用户可以使用 Firebug 对该表单进行完全相同的修改,但最后我检查没有人将 Firebug 称为安全向量。
最后一个元素是这样的概念:使用服务器端代理,在将结果传递给客户端之前可以更强大地过滤结果。然而,无论是 PHP 还是 Javascript,我都可以过滤结果以删除 、onclick 或 iframe 等内容。当然,某些客户端可以更改我的 javascript 函数来删除过滤,但过滤只会影响他们特定的客户端体验,不会为其他用户更改,从而防止永久性的多客户端 XSS 攻击。
显然,服务器端代理有一些好处,因为它可以使记录潜在 XSS 攻击等事情变得更容易,但就防止攻击本身而言,PHP 和 Javascript 似乎都有足够的实用程序。在某些方面,JSONP 实际上比简单的 标记更安全,因为至少使用 JSONP 时,结果会通过一个函数,这意味着它会经过某种过滤,而不仅仅是全面信任,正如
所发生的那样。
是否存在我遗漏或忽视的风险?如果我正确理解了这个问题,那么使用 JSONP 包含我们信任的来自我们信任的来源的文件的内容就不存在安全风险。这是一个准确的评估吗?
解决方案
如果两端都是可信的,那么 JSONP 就没有危险(它基本上只是一个
标记)。
脚本/JSONP都具有相同的安全漏洞,因为它们是自动执行的,而不是简单地作为数据传输。使用服务器端代理意味着跨域返回作为数据传递,并且可以过滤恶意内容。如果跨域完全可信,那么 JSONP/SCRIPT 是安全的,如果有任何风险嫌疑,则通过过滤代理传递。
In our web application we have run into the situation where we need to do a cross-domain AJAX calls from one domain we fully control to another domain we fully control. I've been surfing around for the best solution and the two that come to mind are a local file proxy (local file using php::fopen) or jquery/JSONP.
When I look up online I see people routinely talk about how it is dangerous to use JSONP because someone could inject malicious data with it. The dilemma is that most of the arguments against it do not seem to hold much water so I'm coming here to ask the Stack for clarification.
What are the specific vectors of attack which would be opened up by cross domain JSONP?
From my understanding the only vector for JSONP is the exact same vector which is opened up by including a <script>
tag on your site whose src is to any site that is not controlled by you: That they could turn malicious and start farming user sessions/cookies/data. If that is true, then it would seem that it is not the protocol (JSONP) that is the concern, but rather the source that the data is gathered from.
Because whether it was a server-side proxy, a <script>
tag, or ajax/JSONP the risk is that I'm putting someone else's content on my page, and they could start farming user sessions if they felt obliged (in a way that's exactly what Google analytics does by way of a script tag).
Many vectors that I hear online hinge upon improper validation of user submitted forms and data. In example, JSONP is used to pull some file, which puts data in a form, and then the form is submitted for database insertion. If the data from that form is trusted, because it's from believed-to-be-secure source (JSONP data), and put in without validation, then again it's not the JSONP at fault, but rather improperly validated user input. A user could make the exact same modifications to that form using Firebug, but last I checked no one is calling Firebug a security vector.
The last element is the notion that with the server-side proxy there is a greater ability to filter the results prior to passing it to the client. Yet, whether it is PHP, or Javascript I could filter the results to remove things like , onclick or iframe. Sure, someone client side could alter my javascript function to remove the filtering, but the filtering would only affect their specific client experience, and would not be altered for other users, thus preventing a permanent multi-client XSS attack.
Obviously, there are some benefits to the server side proxy because it would make things like logging potential XSS attacks easier, but in terms of preventing the attack itself both PHP and Javascript seem to have adequate utilities. In some ways, it would seem JSONP is actually more secure than a simple <script>
tag because at least with JSONP the result passes through a function which means it somewhat filtered, rather than just blanket trust, as occurs with <script>
.
Is there some risk that I am missing or overlooking? If I understand the problem correctly, then there is no security risk for in using JSONP to include contents of a file we trust from a source we trust. Is that an accurate assessment?
SOLUTION
If both ends are trusted, there is no danger in JSONP (it's basically just a
<script>
tag).Both Script/JSONP hold the same security vulnerabilities because they are automatically executed, rather than simply transmitting as data. Using a server-side proxy means that the cross-domain return is passed as data and can be filtered for malicious content. If the cross-domain is fully trusted, then JSONP/SCRIPT is safe, if there is any suspicion of risk then pass it through a filter proxy.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
server-side-proxy
和当您构建服务器端代理时, javascript代码可以使用
XmlHttpRequest
下载数据。该数据不会自动执行;你必须显式地做一些愚蠢的事情,比如eval()
,才能让它执行。即使数据格式是 JSON 并且其他服务器已受到损害,并且您自己的服务器端代理没有受到损害,您的客户端代码仍然有可用的防线。例如,您可以使用 安全 JSON 解析器,并拒绝恶意脚本。但是,当您使用 JSONP 或
标记时,您会直接包含其他人的代码。因为它的代码(而不是数据),浏览器会自动执行它,而不给您机会检查或修改它。
总而言之,服务器端代理为您提供了两道额外的防线 -
There is a BIG difference between
server-side-proxy
and<script>/JSONP
. In the first case, you download data, in the latter you download and automatically execute codeWhen you build a server-side-proxy, the javascript code can use
XmlHttpRequest
to download data. This data will not execute automatically; you have to explicitly do something stupid, likeeval()
, to get it to execute. Even if the data format is JSON and the other server has been compromised and your own server-side-proxy doesn't catch the compromise, you still have a line of defense available your client code. You can, for example, parse the JSON using a safe JSON parser, and reject malicious script.But when you use JSONP or a
<script>
tag, you are directly including someone else's code. Because its code (and not data), the browser automatically executes it, without giving you a chance to inspect or modify it.To summarize, server-side-proxy gives you two additional lines of defence -
当您控制请求的两端时,大多数关于 JSONP 的传统安全性担忧都不再是问题。
您将遇到的另一个问题是,作为一种安全措施,某些用户会阻止第三方脚本。这也会阻止您的 JSONP 请求。服务器端代理方法不存在这个问题。
When you control both ends of the request, most of the traditional security worries about JSONP aren't an issue.
One additional problem that you'll encounter is that some users block third-party scripts as a security measure. That will block your JSONP requests as well. The server-side proxy approach does not have that issue.