当存在 JSONP 和 CORS 等解决方法时,为什么浏览器具有同源策略?

Why do browsers have Same-Origin policies when workarounds like JSONP and CORS exist?

这个问题有点重复:

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

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

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

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

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

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

这里的重点是保护您的页面,以便 XSS is not possible in the first place. To do this the focus should be on correctly encoding text that is output to the page. This will prevent 'phoning home' as an attack will not be possible in the first place. A Content Security Policy can help neutralise any script that manages to slip through the net. A regular security vulnerability assessment on your website should pickup unencoded output - think of the CSP as filling in the gaps between when these are found and fixed, although browser support 还没有完全存在 - 特别是在 Internet Explorer 中。

However, XMLHttpRequest does not allow this, so Company.com must use JSONP, but this would prevent the scrubbing of data and could result in an Attacker injecting arbitrary Javascript onto the page. How is this a better solution?

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

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

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

仅允许 company.com client-side 通过用户浏览器通过 HTTPS 访问数据。

在此 CORS 方案中,example.com 信任 company.com 仅针对该特定请求的数据响应。与 Access-Control-Allow-Credentials header 结合,他们可以选择请求用户在其浏览器上发送任何授权 cookie,并由 JavaScript 在 [=15= 读取响应].

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

In other words, in what scenario does a locked-down XMLHttpRequest actually provide a greater degree of security?

互联网上无处不在。

假设您登录了 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 的服务将尽职地 return 您收件箱的内容。

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

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

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