JavaScript document.domain:Uncaught DOMException:阻止了源为...的框架

15

在测试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(),你将会得到一个错误

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

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

3个回答

10

这个错误不是一个 bug。同源策略是一种安全机制,确保窗口对象只有访问它们被授权获取的信息。在您的情况下,这包括访问 opened.location

在创建时,两个标签具有相同的起源(origin),这使得第一个标签可以访问opened.location。但是在调用document.domain = 'www.google.com'之后,他们不再具有相同的起源(origin)了。

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

是的,但它有点更复杂。起源(Origin)由方案/主机/端口三元组定义,请参见 @TheUnknown 的答案以了解更多详细信息。方案和主机始终保持不变,并且它们是包含在 window.location.origin 字符串中的部分。

需要知道的棘手问题是,任何对document.domain的调用,包括document.domain = document.domain, 将导致端口号被重写为null,从而导致两个标签的起源(origin)之间存在差异,防止它们之间通信信息,例如opened.location,从而导致错误。

信息来源于 MDN 的同源策略指南


在这两种情况下,端口均为 null - 在设置之前和之后都是如此。仅当明确在域中设置端口时,端口才会被设置。 - Derek Pollard
typeof window.location.port 在任何情况下都不会改变 - Derek Pollard
一个很好的测试你的理论的方法是尝试在IE上复制问题 - 如果是端口的问题,IE不应该有这个问题,因为它不会进行端口检查。 - Derek Pollard
浏览器会单独检查端口号,这可能意味着无法通过window.location.port中的值复制同源检查。 - Nino Filiu
端口 IE在同源检查中不包括端口。 - Derek Pollard
显示剩余6条评论

4

首先,我建议您阅读同源策略

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

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

在这种特定情况下,您使用HTTPS协议打开一个窗口,但是当您设置域时,协议被更改为HTTP,请参见下面的图像:

protocol has changed

根据1,如果协议不同,则违反了原则,因此您会得到错误

Uncaught DOMException: Blocked a frame with origin "https://www.google.com" from accessing a cross-origin frame.

这里的关键词是跨域

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


1
嗯,我还不太确定。你的回答确实是一个好的输入,但是当使用http://example.com而不是https://google.com时,同样的错误也会出现。 - Nino Filiu
1
鼠标悬停在 document.location 更改之前和之后是相同的;它们都是 http://www.google.com - Derek Pollard
1
@TheUknown 如果你在OP的问题中用http://example.com替换每个 https://www.google.com,错误仍然会显示。 - Nino Filiu
明白了。我没有测试那部分,需要进行更多的研究。 - Polynomial Proton
1
我已经找到了答案,目前正在编辑!只是提供信息。 - Nino Filiu
显示剩余2条评论

0

这可能有点不太具体(只是陈述事实),但是:

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

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

这让我想到,修改document.domain被认为是潜在的不安全行为,并且会通过孤立子窗口来“惩罚”。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接