为什么用户脚本管理器仍然支持使用 unsafeWindow?

Why do userscript managers still suport the use of unsafeWindow?

unsafeWindow API 使得用户脚本可以与脚本执行页面的变量和函数交互。但是,强烈建议不要这样做,因为网站可能会通过 unsafeWindow 劫持用户脚本并让它们执行恶意代码。但是,为什么 unsafeWindow 甚至是必要的,为什么仍然使用它?在 Firefox 39 之前,用户可以使用位置 hack 作为 unsafeWindow 的替代方法。由于 Firefox 39 中的更新对此进行了修补,此 hack 最终停止工作。尽管如此,用户仍然可以在隔离的沙箱中使用 GM APIs 并通过这样的脚本标签插入代码:

const fnToRunOnNativePage = () => {
  console.log('fnToRunOnNativePage');
};

const script = document.body.appendChild(document.createElement('script'));
script.textContent = '(' + fnToRunOnNativePage.toString() + ')();';
// to use information inside the function that was retrieved elsewhere in the script,
// pass arguments above
script.remove();

我从这个 Whosebug post 得到了这段代码:

那为什么unsafeWindow还能用呢?上面的代码几乎是 unsafeWindow 的完美替代品。另请注意,unsafeWindow 在 Greasemonkey 和 Tampermonkey 中的运行方式有何不同?谢谢。

外部资源:

我们调用创建一个<script>标签并将其插入页面脚本注入.

脚本注入有一些缺点。引用 Brock Adams:

  1. The script, at least the injected parts, cannot use the enhanced privileges (especially cross-domain) provided by the GM_ functions -- especially GM_xmlhttpRequest().
  1. Can cause side effects or conflicts with the page's JS.
  1. Using external libraries introduces even more conflicts and timing issues. It's nowhere near as easy as @require.
    @require, also runs the external JS from a local copy -- speeding execution and all but eliminating reliance on an external server.
  1. The page can see, use, change, or block the script.
  1. Requires JS to be enabled. Firefox Greasemonkey, especially, can run on a page which has JS blocked. This can be godsend on bloated, crappy, and/or intrusive pages.

因此,一些开发人员可能更喜欢使用 unsafeWindow 而不是脚本注入。删除 unsafeWindow 会让他们的事情变得更难。

unsafeWindow 通常 可以正常工作 ,而且它比创建和注入脚本标签更简单。

另一个问题是,在网络上,向后兼容性经常是最重要的因素之一,很少(如果有的话)被放弃。如果某些东西在 2015 版本中工作,一般的理念是它也应该在 2020 版本中工作,而不需要任何在 2015 版本上工作的人回来修复它(因为他们可能不再这样做了) . 。虽然用户脚本管理器 不像网络上的其他东西那样关心向后兼容性,同样的推理适用 - 避免破坏当前工作的东西,除非你有 很好的理由.

除了CertainPerformance的出色解释外,unsafeWindow只是作为window.wrappedJSObject的别名实现的。

我自己作为脚本管理器开发人员,最初,我抵制 unsafeWindow 的实现,但后来为了兼容性不得不添加它。

出于安全原因,现代浏览器将扩展程序注入的 JavaScript 与网页 JavaScript 分开。

Firefox 使用专用的 userScripts API 与扩展程序自己的脚本相比进一步限制了用户脚本(即第 3 方脚本)的访问。

桥接这些分离的 scopes/contexts(页面、扩展、用户脚本)会增加安全问题。

但是,有时需要这种交互来覆盖(不需要的)页面 JavaScript,这可能是一件好事,或者获取存储在页面 JavaScript.[=15= 中的数据]

总而言之,尽管 unsafeWindow 可能会产生不安全的桥接,但它不是新桥,并且 window.wrappedJSObject 已经可以使用相同的访问权限。