JSONP 可以安全使用吗?
Posted
技术标签:
【中文标题】JSONP 可以安全使用吗?【英文标题】:Is JSONP safe to use? 【发布时间】:2010-10-11 11:13:34 【问题描述】:在使用 JSONP 时有哪些安全问题需要考虑?
【问题讨论】:
该网站确实是一个安全的网站..我只想知道我的服务器存储的cookie是否存在安全问题。 naugtur 下面的链接提供了一个很好的解决方案,并对它如何被破坏以及解决方案如何工作进行了深入的解释。请看一看。 解决问题的相关问题:Is it possible to make a secure JSONP request? 提交的任何数据都显示为 GET 请求的查询参数,因此可能会被记录等,这是一个问题吗? 【参考方案1】:更新:JSONP 是一种常见的跨域请求方法。现代浏览器现在有跨域资源共享,IE8+ 有类似的 XDomainRequest。请参阅http://enable-cors.org/ 了解更多信息。
JSONP 只是一个脚本包含,允许您使用回调。但是,您应该注意Cross-site request forgery (CSRF)。
只要您控制脚本和服务器,JSONP 就不再比脚本包含不安全。除非您有一个向登录用户返回敏感数据的 JSONP 服务。恶意站点可以向服务发送请求(希望用户登录到您的站点),然后检索数据。该服务可以检查请求的引用者,但可以使用 flash 来欺骗引用者(感谢 Chris Moschini)。
想象一下这个情景: - 用户登录他的网上银行账户。在用户浏览器中存储会话 cookie。该站点有一个 jsonp 服务,其中包含有关用户及其帐户的敏感信息。 - 其他站点不会知道用户已登录,但他们可以大胆猜测并尝试访问 jsonp 服务。由于用户有一个会话 cookie,浏览器会得到响应,并且没有什么可以阻止网站执行 ajax 发布以将敏感数据保存在其服务器上。
2012 年 6 月 28 日更新:如果您想防止 CSRF 攻击,您应该阅读安全专家的这篇深度博文:http://erlend.oftedal.no/blog/?blogid=130
【讨论】:
其他地方已经指出 HTTP_REFERER 可以被 Flash 欺骗,因此服务器通过 jsonp 提供的任何敏感数据都容易受到攻击。 这只是风险的一方面。 naugtur 的链接显示了风险的另一面,并为该部分提供了更好的解决方案。【参考方案2】:是的,您需要小心,但如果与受信任的服务一起正确使用,它是相对安全的。
据我了解,以下是 JSONP 安全问题的摘要:
从消费者的角度来看:
您必须相信提供程序不会返回恶意 javascript,而不是您指定的 JSONP 回调中包装的预期 JSON。 任何第三方 JavaScript 嵌入式插件(例如 Google Analytics)也是如此。 它与 XSS 攻击的唯一相似之处在于它允许第 3 方在您的应用程序中执行任意 JavaScript,但是,您必须首先通过发出请求来选择信任第 3 方。从提供者的角度来看:
您不得假设即使请求中存在客户的 cookie,消费者也是您控制的网页。根据授权 URL 的白名单检查 Referer 标头,和/或不要依赖基于 cookie 的身份验证。 类似于 CSRF / 混淆代理攻击。【讨论】:
【参考方案3】:双方都存在安全问题。最严重的是包含 JSONP 的网站。
如果您包含来自另一个域(您无法控制)的域,则该域可以随时更改脚本。他们可以使 javascript 在您的网页上下文中执行任何您自己的 javascript 可以执行的操作。如果您使用 JSONP,则无法解决此问题。您应该研究使用 iframe 进行跨域通信,这最好由出色的 EasyDXM 库完成。
如果您提供处理 JSONP 的 Web 服务,则必须防止跨站请求伪造 (CSRF)。这是您的网络服务向登录用户返回敏感信息的地方。如果用户已登录您的站点,则任何其他站点都可以向 JSONP 服务生成 GET 请求,并且您的域的 cookie 会随请求一起提交——本质上是对登录用户进行身份验证——除了现在,远程域获得响应并能够读取敏感数据!
防止 CSRF 的最佳方法是生成一个随机数(一个难以猜测的随机生成的数字)并将其存储在会话中。在您网页上的所有表单中输出此随机数,并将其包含在您网页上的所有 JSONP 请求中。在服务器上,确保请求中的 nonce 存在且正确(无论是 GET、POST 等)。其他域将无法猜测此 nonce,因此无法获取敏感信息,尽管有 cookie正在发送。
最后,还有另一种安全问题:JSONP 根本不支持浏览器中的用户身份验证,而 OAuth 则可以。当然,您可以让服务器获取某种访问令牌(例如使用 OAuth)并使用它。但是,如果您想完全在浏览器中进行身份验证,则必须使用 iFrame 进行跨域通信。我认为这就是 OAuth 2.0 的做法。以下是您的设置方式:您网站上托管的页面可以完全访问您的服务器。拥有一个加载 EasyDXM 并使用它为您的网站设置隐藏 iframe 的 javascript 库,并使用它与之对话。
【讨论】:
【参考方案4】:JSONP 绝对不安全,因为它只是将跨域的任何东西作为 JavaScript 运行。
解决方案!解决方案!
创建一个 iframe,最好是一个沙盒 iframe,并在那里加载 JSONP。捕获结果并通过window.postMessage
传递它
是的,像往常一样,有人首先想到了这个想法 :)
博客文章不再存在,但我将链接保留在此处以供信用: http://beebole.com/blog/general/sandbox-your-cross-domain-jsonp-to-improve-mashup-security/ 编辑:wayback machine link
它使用 window.name hack 进行 iframe 通信,但那是针对 IE6 和 7。
【讨论】:
以上是关于JSONP 可以安全使用吗?的主要内容,如果未能解决你的问题,请参考以下文章
使用 jQuery 请求 JSONP 时,我可以使用静态(即预先确定的)回调函数名称吗?