为什么显示远程网页的简单 HTTP 请求不违反同源策略?

信息安全 http 同源策略 远程服务器
2021-08-23 14:39:22

W3Schools 页面上,我发现 HTTP 请求的工作方式如下:

  • 客户端(浏览器)向 Web 发送 HTTP 请求
  • Web 服务器接收请求,并运行应用程序来处理它
  • 服务器向浏览器返回一个 HTTP 响应(输出)
  • 客户端(浏览器)接收响应。

在同一页面上,我发现XMLHttpRequest的工作方式如下:

  • 浏览器创建一个 XMLHttpRequest 对象并将其发送到服务器
  • 服务器处理请求,创建响应并将数据发送回浏览器
  • 浏览器使用 JavaScript 处理返回的数据并更新页面内容。

以上两个过程在我看来几乎相同。但是,如果服务器在远程域上运行,则后者违反了同源策略 (SOP)。Stack Overflow 上关于 open() 方法中的 URL 的这个问题

由于我们只能向我们自己的 Web 服务器发送请求,我假设我们不必在 URL 中重写网站名称。

将相同的逻辑应用于第一种情况(HTTP 请求)意味着如果网页不在我自己的计算机上,我将无法打开它。幸运的是,情况并非如此。

那么,为什么显示远程网页的 HTTP 请求不违反 SOP?这里的关键点/区别是什么?

我认为这是关于第二个进程(XMLHttpRequest)是从脚本启动的,而第一个进程是由用户触发的。但是,当我单击网页上的超链接时,不是从脚本发送的 HTTP 请求吗?Web 服务器如何区分来自脚本的请求和来自用户的请求?

4个回答

Web 服务器如何区分来自脚本的请求和来自用户的请求?

它没有。同源策略由浏览器执行,而不是服务器。

同源策略 (SOP) 的目的不是保护服务器本身。相反,它是为了保护服务器希望与用户共享但不与其他方共享的机密信息。当用户发送请求时,可以通过检查用户的 cookie、身份验证标头或 IP 地址来保护这些信息,但是攻击者可以绕过这些检查,让合法用户使用脚本打开攻击者的网站来请求信息。

这是 SOP 提供保护的时候。请求可能仍会发送,但浏览器可以拒绝让脚本查看响应中的信息。

如果需要保护服务器免受可能基于对用户的信任而被欺骗执行的潜在有害请求,那么 SOP 是不够的。此时服务器需要其他技术来防御 CSRF

如果一个人在浏览器中输入一个 URL,则会从一个新的空源开始,即最初没有域和端口属于该源。一切都可以放入具有空原点的窗口/选项卡中,一旦将其放在那里,原点就会根据数据的来源而改变。

如果从加载的网页内部调用 HTTP 请求,则从非空源开始。在这种情况下,同源策略开始起作用并限制可以从这个非空源内部执行的操作。

请注意,如果已经在浏览器中加载了一个页面,并且现在替换了 URL 栏中的 URL,则同源策略不适用,因为这个新 URL 不是从窗口/选项卡内部调用的,而是从外部调用的。因此它将再次以空原点开始。

对您的问题的简单回答是“显示网页的请求”是设置来源的原因,因此显然它们不能违反同源政策。由于同源策略,页面内发生的事情(例如 JS 执行,尤其是 XHR/Fetch)受到各种限制,但始终允许顶级导航*。

* 一般的 iframe,尤其是沙盒的 iframe,在这里有点奇怪。iframe 是父页面来源的一部分,但其内容是 iframe src 来源的一部分(可能完全不同!)。跨域父/iframe 关系的交互受到严重限制,类似于任何两个跨域页面,但值得注意的例外是默认情况下可以导航另一个(也就是说,页面可以设置src它们包含的 iframe,而 iframe 可以设置location它们的父级(尽管 iframe不能将位置设置为 ajavascript:data:URI,因为这会将内容注入到父级的源中)。可以sandbox iframe 使得它们无法执行父导航......或者实际上它们根本无法执行 JS!

区别很简单:计算机用户选择在浏览器中输入哪个网站地址。他们不会选择该站点然后尝试与之交换信息的网站地址。

这一关键区别意味着我们需要保护后者,而不是前者。

当然,对前者的等效保护意味着您实际上根本无法导航到任何网站。在某些时候,您需要一个“原始”来源,因此我们将其定义为用户在其浏览器窗口中键入的来源。

这是关于信任、关于选择、关于控制以及关于防止恶意网站程序员(包括那些可能修改了其他良好网站代码的“中间人”)的保护。用户通常不应该期望自己得到保护,如果没有一些读心机制,这样的事情通常也不可行。

当然,即使是原始 HTTP 请求也可能受到攻击(拦截和修改或静默重定向),但这就是我们拥有 HTTPS 的原因。