为什么跨域 JSONP 安全,而跨域 JSON 不安全?
我在连接最近了解 JSONP 的一些点时遇到了困难。我的理解是:
- 由于同源政策,禁止任何内容(包括 JSON)的跨域 XmlHttpRequest。这可以防止 XSRF。
- 您可以拥有一个带有返回 JSONP 的 src 的脚本标记 - 一些 JSON 填充在对 Javascript 函数的调用中(例如“Foo”)。
- 您可以在页面上实现“foo”,当 JSONP 调用时,该页面将被调用返回数据,然后可以使用函数传递的 JSON 数据执行操作
为什么通过 JSONP 接收跨域数据可以,但通过 JSON 接收跨域数据就不行?
是否存在这样的假设:JSON 倾向于允许 XSRF 而 JSONP 则不允许?如果是这样,除了 JSONP 是某种事实上的数据格式,永远不会提供支持 XSRF 的数据之外,还有什么原因吗?为什么选择 JSONP 而不是 XML 上的任意根标记?
预先感谢您的回答,请在未能解决这个问题后让我的大脑再次运转。
I'm having trouble connecting some dots having recently learned of JSONP. Here's my understanding:
- Cross-domain XmlHttpRequests for any content (including JSON) is banned, due to the same origin policy. This protects against XSRF.
- You are permitted to have a script tag with a src that returns JSONP - some JSON padded inside a call to a Javascript function (say 'Foo')
- You can have some implementation of 'foo' on the page that will get called when the JSONP data is returned, and you can do things with the JSON data that function is passed
Why is it OK to receive cross-domain data if it came via JSONP, but not if it came via JSON?
Is there an assumption that JSON is prone to permitting XSRF but JSONP is not? If so, is there any reason for that other than JSONP being some de-facto data format that won't ever provide data that enables XSRF? Why JSONP and not some arbitrary root tag on XML instead?
Thank you in advance for your answers, please make my brain work again after failing to figure this one out.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我理解这个问题是关于为什么浏览器认为 JSONP 安全,而不是关于它是否安全(事实并非如此)。我将逐步解答这个问题。
常规 AJAX
为了执行常规 AJAX 请求,浏览器创建一个 XHR 对象,将其指向 URL 并提取数据。 XHR 对象仅信任来自同一域的数据。这是一个硬限制。在当前的浏览器中无法绕过它(编辑 - 您现在可以使用 CORS)。
解决方案 - 不要使用 XHR
由于 XHR 受相同域策略的约束,我们不能使用 XHR 进行跨域 AJAX。幸运的是,还有其他方法可以访问远程服务器。例如,我们可以将图像标签附加到页面。我们还可以附加一个脚本标签,并为其指定一个指向远程服务器的 src 属性。例如,我们可以从 CDN 中提取 JQuery 并期望它能够工作。
JSONP 的工作原理。
当我们发出 JSONP 请求时,我们的代码动态地将脚本标记附加到页面。 script 标签有一个 source 属性,该属性指向远程 JSONP API url,就像您从 CDN 插入脚本一样。
服务器返回的 JSONP 脚本包装在函数调用中。下载脚本后,该函数将自动执行。
这就是为什么我们必须告诉 JSONP 我们想要包装脚本的回调函数的名称。一旦脚本下载完毕,就会调用该函数。
安全问题
这里存在一些相当大的安全问题。您正在下载的脚本可能会控制您的页面并使您的用户面临风险。 JSONP 对于您的用户来说并不安全,它只是没有被 Web 浏览器阻止。 JSONP 实际上是我们正在利用的一个浏览器漏洞。谨慎使用。
如果使用得当,JSONP 是相当棒的。
I understand this question to be about why the browser considers JSONP safe, not about whether it is safe (which it isn't). I will address this question step by step.
Regular ol' AJAX
To perform a regular AJAX request, the browser creates an XHR object, points it at the URL and pulls the data. The XHR object will only trust data from the same domain. This is a hard limitation. There is no getting round it in current browsers (edit - you can now use CORS).
Solution - Don't use XHR
Since XHR is subject to the same domain poilicy, we can't use XHR to do cross domain AJAX. Luckily, there are other ways to hit a remote server. We could append an image tag to the page for example. We can also append a script tag and give it a src attribute that points to the remote server. We can pull JQuery from a CDN for example and expect it to work.
How JSONP works.
When we make a JSONP request, our code dynamically appends a script tag to the page. The script tag has a source attribute which points to the remote JSONP API url, just as though you were inserting a script from a CDN.
The JSONP script returned by the server is wrapped in a function call. When the script is downloaded, the function will be executed automatically.
This is why we have to tell the JSONP the name of the callback function we want to wrap the script in. That function will be called once the script has downloaded.
Security concerns
There are some fairly big security concerns here. The script you are downloading could take control over your page and put your users at risk. JSONP is not safe for your users, it is just not blocked by the web browsers. JSONP really is a browser exploit which we are taking advantage of. Use with caution.
Used wisely, JSONP is pretty awesome though.
我不知道 JSONP 是安全的观念是如何产生的,但是看看
和
均引用自 http://json-p.org/ 。
其他链接,其中包含有关 JSONP/安全性的一些有用信息:
所有这些都告诉我们有两件事 - 基本上它不被认为是“安全”的,但是有一些关于如何使其“更安全”的想法......尽管大多数想法依赖于标准化和内置于浏览器等中的特定检查逻辑。
I don't know how the perception that JSONP is safe came up but see
and
both quotes from http://json-p.org/ .
other links with some useful information about JSONP/security:
all these tell 2 things - basically it is not considered "safe" but there are ideas on how to make it "safer"... though most ideas rely on standardization AND specific check logic to be built into browsers etc.