当 JSONP 和 CORS 等变通方法存在时,为啥浏览器会有同源策略?

Posted

技术标签:

【中文标题】当 JSONP 和 CORS 等变通方法存在时,为啥浏览器会有同源策略?【英文标题】:Why do browsers have Same-Origin policies when workarounds like JSONP and CORS exist?当 JSONP 和 CORS 等变通方法存在时,为什么浏览器会有同源策略? 【发布时间】:2015-04-29 07:11:03 【问题描述】:

这个问题有点像:Why same origin policy for XMLHttpRequest

但是,这个答案并不令人满意,因为它没有解决存在变通办法的事实(如问题中所述)。答案仅解决与 XMLHttpRequest 直接相关的安全问题,但 JSONP 仍然存在这些问题(可能还有 CORS,不确定)。所以问题仍然存在 - 为什么有一个严格的同源政策,当有像 JSONP 这样可以说更糟糕的变通办法时(因为它是可执行的而不是静态内容)?

这是一个例子: Company.com 想要对一些未受保护的资源进行 AJAX 调用,例如用于某些数据查找的简单公共 API。 Company.com 意识到这可能不安全,因此他们会仔细清理数据以确保没有有趣的业务。但是,XMLHttpRequest 不允许这样做,因此 Company.com 必须使用 JSONP,但这会阻止数据的擦除,并可能导致攻击者将任意 javascript 注入页面。这是一个更好的解决方案吗?

另一个例子: Company.com 存在漏洞,攻击者能够将 Javascript 注入页面,然后某些用户可以查看该页面(发生这种情况的方式有上百万种;这可能是最常见的网站攻击)。使用严格的同源策略,攻击者可以整天乱搞页面,但他不能“打电话回家”,这是一个重要的细节,因为这意味着您的所有数据都是安全的。但是 JSONP(和图像标签)通过允许攻击者从页面上抓取您的所有个人数据并将其发送到任何地方来打破这一点。即使使用 CORS,这仍然是现实,因为我可以告诉我的恶意服务器允许来自任何域的入站 XS 请求。

换句话说,在什么场景下,锁定的 XMLHttpRequest 实际上提供了更高程度的安全性?

【问题讨论】:

如果操作不当,JSONP 实际上是不安全的。见JSONP hijacking. 我不认为你读过这个问题。重点是 JSONP 不安全。 【参考方案1】:

你的前提不正确。同源策略没有说明网页包含外部域资源的能力。它可以防止通过脚本直接访问由不同 Origin 拥有的资源,而无需他们选择加入。

因此,CORS 和 JSONP 不是同源策略的解决方法。 CORS 使 Origin 可以选择加入带有响应的 XHR 请求,而 JSONP 只是一种允许外部引用将动态数据返回到页面的 hack。

这里的重点是保护您的页面,以便首先无法使用XSS。为此,重点应放在correctly encoding text that is output to the page。这将防止“打电话回家”,因为首先不可能进行攻击。 Content Security Policy 可以帮助消除任何设法通过网络溜走的脚本。您网站上的定期安全漏洞评估应该获取未编码的输出 - 将 CSP 视为填补发现和修复这些漏洞之间的空白,尽管 browser support 尚未完全存在 - 特别是使用 Internet Explorer。

但是,XMLHttpRequest 不允许这样做,因此 Company.com 必须使用 JSONP,但这会阻止数据擦除,并可能导致攻击者将任意 Javascript 注入页面。这是一个更好的解决方案吗?

事实并非如此。 CORS 是更好的解决方案,因为请求检索数据而不是可执行代码。 CORS 允许 XMLHttpRequest 执行此操作。

使用 CORS 响应标头 Access-Control-Allow-Originexample.com 的网站所有者可以将其设置为

Access-Control-Allow-Origin: https://company.com 

只允许company.com 客户端通过用户浏览器通过 HTTPS 访问数据。

在这种 CORS 方案中,example.com 仅信任 company.com 对该特定请求的数据响应。结合Access-Control-Allow-Credentials 标头,他们可以选择在浏览器上向用户请求任何授权cookie,并将其与请求一起发送,并通过company.com 的JavaScript 读取响应。

在 JSONP 场景中,company.com 将信任 example.com 以及 他们的整个 Origin。这意味着他们信任 example.com 的整个客户端站点安全模型。 Example.com 可以对company.com 的网站做任何想做的事情。因此,如果example.com 被黑客入侵,他们还可以在每个用户访问包含<script src="https//example.com/... 标签的页面时控制company.com 用户会话。

换句话说,在什么场景下,锁定的 XMLHttpRequest 实际上提供了更高程度的安全性?

互联网上的任何地方。

假设您已登录 Gmail。为了论证的缘故,假设 Gmail 有一个 AJAX 方法来获取您的收件箱内容:

https://gmail.com/services/inbox/get_conversations

现在,您正在上网并登陆我的网站,evil.com

Evil.com 包含一些 JavaScript 以向 https://gmail.com/services/inbox/get_conversations 发出 POST 请求,当您登录时,这会将您的 cookie 从 gmail.com 发送回 gmail.com

https://gmail.com/services/inbox/get_conversations 的服务将尽职尽责地返回您收件箱的内容。

如果没有同源策略将其锁定,evil.com 将能够读取此响应中的数据。即任何网站都可以阅读您的电子邮件。使用同源策略,数据将返回到浏览器,但除了gmail.com(当然还有 CORS 允许的任何其他源)之外,没有客户端脚本可以读取它。例如,在这种情况下,Google 可能允许以下行为:

Access-Control-Allow-Origin: https://google.com

注意:以上所有内容都是我为了说明目的而编造的,绝不反映 Google 和 Gmail 是如何实际做到这一点的。原则上是一样的。

【讨论】:

所以您的意思是:“如果您在您的网站上实施了 CORS,并且您的网站没有被黑客入侵,那么您的端点就是安全的。”这是正确的,但它没有回答我的问题。我的网站无法阻止对不受信任域的出站请求。使用您的示例,如果我向您发送带有一些恶意 javascript 的电子邮件,我可以使用 cors、jsonp 等将您的所有私人数据发送到我的服务器。 同源策略不会阻止页面引用外部资源,因此 CORS 和 JSONP 不是它的解决方法。这里的重点是保护您的页面,这样一开始就不可能出现 XSS。这将防止'打电话回家'。查看内容安全政策以获得额外帮助,但请检查对目标浏览器的支持。 啊哈,这就是我要找的答案。编辑您的答案以包含此内容,我会接受。

以上是关于当 JSONP 和 CORS 等变通方法存在时,为啥浏览器会有同源策略?的主要内容,如果未能解决你的问题,请参考以下文章

跨域访问JSONP CORS

如何解决 Ionic2 中的 CORS 问题和 JSONP 问题

跨域问题解决方案

跨域 JSONP, CORS

关于安全性问题:(XSS,csrf,cors,jsonp,同源策略)

JSONP原理解析