JSONP 使用安全吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/613962/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is JSONP safe to use?
提问by
Are there any security issues that should be considered when using JSONP?
使用 JSONP 时是否应考虑任何安全问题?
回答by gregers
Update: JSONP is a common hack to do cross-domain requests. Modern browsers now have Cross Origin Resource Sharing, and IE8+ have XDomainRequest which is similar. See http://enable-cors.org/for more info.
更新:JSONP 是一种常见的跨域请求技巧。现代浏览器现在具有跨域资源共享,IE8+ 具有类似的 XDomainRequest。有关更多信息,请参阅http://enable-cors.org/。
JSONP is just a script include that allows you to use a callback. You should however be aware of Cross-site request forgery (CSRF).
JSONP 只是一个允许您使用回调的脚本包含。但是,您应该注意跨站点请求伪造 (CSRF)。
As long as you control the script and the server, JSONP isn't anymore insecure than a script include. Unless you have a JSONP-service that returns sensitive data to logged in users. A malicious site can send a request to the service (hoping that the user is logged in on your site), and retreive the data. The service can check the referrer of the request, but it is possible to spoof the referrer using flash (thanks Chris Moschini).
只要您控制脚本和服务器,JSONP 就不会比脚本包含更不安全。除非您有一个向登录用户返回敏感数据的 JSONP 服务。恶意站点可以向服务发送请求(希望用户登录您的站点),并检索数据。该服务可以检查请求的引用者,但可以使用 flash 欺骗引用者(感谢 Chris Moschini)。
Imagine this senario: - A user logs into his internet banking account. Storing a session cookie in the users browser. This site has a jsonp service with sensitive info about the user and his accounts. - Other sites won't know that the user is logged in, but they could do a wild guess and try to access the jsonp service. Since the user has a session cookie, the browser will get a response, and there's nothing stopping the site from doing an ajax post to save the sensitive data on their server.
想象一下这个场景: - 用户登录到他的网上银行账户。在用户浏览器中存储会话 cookie。该站点有一个 jsonp 服务,其中包含有关用户及其帐户的敏感信息。- 其他站点不会知道用户已登录,但他们可以随意猜测并尝试访问 jsonp 服务。由于用户拥有会话 cookie,浏览器将得到响应,并且没有什么可以阻止站点执行 ajax 发布以将敏感数据保存在其服务器上。
Update June 28th 2012: If you want to protect against CSRF attacks you should read this in depth blog post by a security expert: http://erlend.oftedal.no/blog/?blogid=130
2012 年 6 月 28 日更新:如果您想防范 CSRF 攻击,您应该阅读安全专家撰写的这篇深入的博客文章:http: //erlend.oftedal.no/blog/?blogid=130
回答by tlrobinson
Yes, you need to be careful, but when used properly with trusted services it's relatively safe.
是的,您需要小心,但是当与受信任的服务正确使用时,它是相对安全的。
Here's a summary of the security issues with JSONP, as I understand it:
以下是我理解的 JSONP 安全问题的摘要:
From the consumer's perspective:
从消费者的角度:
- You must trust the provider to not return malicious JavaScript instead of the expected JSON wrapped in the JSONP callback you specify.
- The same is also true of any third party JavaScript embedded add-ons, such as Google Analytics.
- It's only similar to XSS attacks in that it allows a 3rd party to execute arbitrary JavaScript in your application, however, you must first choose to trust that 3rd party by making the request in the first place.
- 您必须相信提供程序不会返回恶意 JavaScript,而不是您指定的 JSONP 回调中包含的预期 JSON。
- 任何第三方 JavaScript 嵌入式附加组件(例如 Google Analytics)也是如此。
- 它仅与 XSS 攻击相似,因为它允许第 3 方在您的应用程序中执行任意 JavaScript,但是,您必须首先选择通过发出请求来信任第 3 方。
From the provider's perspective:
从供应商的角度:
- You must not assume that even though the clients' cookie(s) are present in the request that the consumer is a webpage under your control. Check the Referer header against a whitelist of authorized URLs, and/or don't rely on cookie-based authentication.
- Analogous to a CSRF / confused deputy attack.
- 即使请求中存在客户的 cookie,您也不得假设消费者是您控制的网页。根据授权 URL 的白名单检查 Referer 标头,和/或不依赖基于 cookie 的身份验证。
- 类似于 CSRF / 混淆的副攻击。
回答by Gregory Magarshak
There are security issues for both sides. The most serious one is for the site including JSONP.
双方都有安全问题。最严重的是包含 JSONP 的站点。
If you are including a from another domain (which you do not control), that domain can change up the script at any time. They can make the javascript do anything in the context of your webpage, that your own javascript could do. There is no way around this if you use JSONP. You should look into cross-domain communication using iframes, which is best done by the excellent EasyDXM library.
如果您包含来自另一个域(您无法控制)的 ,则该域可以随时更改脚本。他们可以让 javascript 在你的网页上下文中做任何你自己的 javascript 可以做的事情。如果您使用 JSONP,则无法解决此问题。您应该研究使用 iframe 的跨域通信,这最好由优秀的 EasyDXM 库完成。
If you are offering a webservice that handles JSONP, you have to protect from Cross-Site Request Forgery (CSRF). This is where your webservice returns sensitive information to logged-in users. If a user has logged into your site, any other site can generate a GET request to the JSONP service, and YOUR domain's cookies are submitted with the request -- in essence, authenticating the logged-in user -- except that now, the remote domain gets the response and is able to read the sensitive data!
如果您提供处理 JSONP 的网络服务,则必须防止跨站点请求伪造 (CSRF)。这是您的网络服务向登录用户返回敏感信息的地方。如果用户已登录您的站点,则任何其他站点都可以向 JSONP 服务生成 GET 请求,并且您的域的 cookie 与请求一起提交——本质上是对登录用户进行身份验证——除了现在,远程域获得响应并能够读取敏感数据!
The best way to protect against CSRF is to generate a nonce (a hard-to-guess, randomly generated number) and store it in the session. Output this nonce in all your forms on YOUR webpages, and include it in all JSONP requests on YOUR pages. On the server, make sure that the nonce is present and correct in the request (whether it be a GET, POST, etc.) Other domains will be unable to guess this nonce, and thus unable to get the sensitive information, despite the cookies being sent.
防止 CSRF 的最佳方法是生成一个 nonce(一个难以猜测的随机生成的数字)并将其存储在会话中。在您网页上的所有表单中输出此随机数,并将其包含在您页面上的所有 JSONP 请求中。在服务器上,确保请求中的 nonce 存在且正确(无论是 GET、POST 等)。其他域将无法猜测此 nonce,因此无法获取敏感信息,尽管有 cookie被发送。
Finally, there is another sort of security issue: JSONP simply does not support user authentication in the browser, of the kind that is possible with OAuth. You can, of course, have the server get some kind of access token (like with OAuth) and use that. However, if you want to do authentication entirely in the browser, you have to use cross-domain communication with iFrames. I think this is how OAuth 2.0 does it. Here's how you set it up: pages hosted on your site have full access to your server. Have a javascript library which loads EasyDXM and uses it to set up a hidden iframe to your site, and talk to it using that.
最后,还有另一种安全问题:JSONP 根本不支持浏览器中的用户身份验证,而 OAuth 可能支持这种身份验证。当然,您可以让服务器获取某种访问令牌(如 OAuth)并使用它。但是,如果要完全在浏览器中进行身份验证,则必须使用 iFrame 进行跨域通信。我认为这就是 OAuth 2.0 的做法。以下是您的设置方式:您网站上托管的页面可以完全访问您的服务器。有一个 javascript 库,它加载 EasyDXM 并使用它为您的站点设置一个隐藏的 iframe,并使用它与它交谈。
回答by naugtur
JSONP is definitely not safe, as it's simply running whatever it gets cross-domain as JavaScript.
JSONP 绝对不安全,因为它只是将跨域的任何内容作为 JavaScript 运行。
solution! solution!
解决方案!解决方案!
Create an iframe, preferably a sandboxed one, and load JSONP there. Catch the result and pass it up via window.postMessage
创建一个 iframe,最好是沙盒框架,然后在那里加载 JSONP。获取结果并通过window.postMessage
And yes, somebody got this idea first, as usual :)
是的,像往常一样,有人首先想到了这个想法:)
The blog post is no longer there, but I'm keeping the link here for credit:
http://beebole.com/blog/general/sandbox-your-cross-domain-jsonp-to-improve-mashup-security/
edit: wayback machine link
该博客文章就不再出现了,但我在这里保持联系信用:
http://beebole.com/blog/general/sandbox-your-cross-domain-jsonp-to-improve-mashup-security/
编辑:回程机链接
It used the window.name hack for iframe communication, but that was for IE6 and 7.
它使用 window.name hack 进行 iframe 通信,但那是针对 IE6 和 7 的。

