JavaScript document.domain未捕获DOMException:阻止了具有来源的框架

时间:2019-02-26 06:29:45

标签: javascript dom same-origin-policy

当我测试SOP时,我遇到这种情况,两个文档与我期望的域具有相同的关系,并且当我尝试获取位置时会引发错误。

重现该问题:

  1. 打开https://www.google.com
  2. 从控制台let opened = window.open("https://www.google.com")
  3. 在同一窗口中执行opened.location.toString(),它将返回正确的位置
  4. 在第二个标签的控制台中执行document.domain = "www.google.com"
  5. 在第一个标签中执行opened.location.toString(),您会收到错误消息

    Uncaught DOMException: Blocked a frame with origin "https://www.google.com" from accessing a cross-origin frame.
    at <anonymous>:1:12
    

有人可以解释这种奇怪的行为吗?

3 个答案:

答案 0 :(得分:3)

首先,我建议您阅读Same-origin Policy

  

同源策略是一种严格的安全机制,它限制了   从一个来源加载的文档或脚本如何与一个   来自另一个来源的资源。它有助于隔离潜在的恶意软件   文档,减少可能的攻击媒介。

     

如果协议,端口(如果指定)和主机都相同,则两个URL的来源相同。您可能会看到这被称为“方案/主机/端口元组”,或仅称为“元组”。 (“元组”是一起组成一个整体的一组项目-双重/三元组/四元组/五元组/等的通用形式。)

在这种情况下,您使用 HTTPS 协议打开一个窗口,但是在设置域时,该协议会更改为 HTTP < / em> ,请参见下图:

protocol has changed

根据1,如果协议不同,则违反了原理,因此会出现错误

  

未捕获的DOMException:阻止了具有来源的帧   通过访问跨域框架获得“ https://www.google.com”。

跨域是此处的关键字。

另外,请查看此SecurityError: Blocked a frame with origin from accessing a cross-origin frame以获得更多详细信息。

答案 1 :(得分:3)

此错误不是错误。同源策略是一种安全机制,可确保窗口对象仅有权访问他们被授权获取的信息。就您而言,这包括可以访问opened.location

创建时,两个选项卡都具有相同的来源,这使第一个选项卡可以访问opened.location。但是在致电document.domain='www.google.com'之后,他们不再了。

“什么?但是在两个标签中,window.location.origin都是相同的”

是的,但是有点复杂。原点由scheme / host / port元组定义,有关更多详细信息,请参见@TheUnknown的答案。方案和主机始终保持不变,它们是window.location.origin字符串中包含的那个。

要知道的一件棘手的事情是,对document.domain的任何调用(包括document.domain = document.domain)都会导致端口号被null 覆盖,从而导致这两个标签的来源有所不同,并阻止了它们之间相互传达诸如opened.location之类的信息,从而导致错误。

从MDN的guide on same-origin policy中提取的信息

答案 2 :(得分:0)

尽管如此,这还是有些信息(只是陈述事实)

  • 在窗口B中更改domain之后,窗口B停止将窗口A记为opener

  • 由于不再将窗口A视为窗口B的打开器,因此禁止访问。

这让我认为,更改document.domain可能被认为是不安全的,并且通过孤立子窗口来“惩罚”。