只要@grant 类型为“none”,使用 unsafeWindow 的 Greasemonkey 脚本是否安全?

问题描述

我编写了一个小的 Greasemonkey 脚本来向 YouTube 添加几个热键,以便在视频不一定具有焦点时控制音量:

// ==UserScript==
// @name     Custom Youtube Hotkeys
// @version  1
// @include  https://www.youtube.com/watch*
// @grant    none
// ==/UserScript==

var customScript_Player = unsafeWindow.document.getElementById("movie_player");

window.onkeypress = function(event) {
  //ignore keypress if focused on search bar
  if (unsafeWindow.document.activeElement.tagName === "INPUT") { return; }
  try {
    if (event.keyCode == 120) {
      customScript_Player.setVolume(customScript_Player.getVolume() + 5);
    } else if (event.keyCode == 122) {
      customScript_Player.setVolume(customScript_Player.getVolume() - 5);
    }
  } catch(err) { console.log(err.message); }
};

但是,我担心使用 unsafeWindow 引起的安全问题。 据我所知,有必要在页面元素上执行 JavaScript,但我看到关于它会带来哪些安全风险的信息相互矛盾。

我看过一些讨论,其中声称使用它打开的唯一安全漏洞来自 Greasemonkey 提供的 API,这些漏洞在脚本标头中使用 @grant none 被阻止,并且只要将 grant 设置为none 页面无法执行任何正常情况下无法执行的操作。

然而,wiki 本身就避免使用 unsafeWindow 发出了几个警告,并且似乎从未指定使用自己的 API 时唯一的问题。

上述脚本安全吗?如果没有,是否有更安全的方法来注入可以控制页面元素的 javascript?

谢谢!

解决方法

我担心使用 unsafeWindow 引起的安全问题。

在 GreaseMonkey 中,用户脚本在 content 脚本上下文中运行,而网页 JavaScript 在 page 上下文中运行。

Xray vision 分隔专门用于防止页面 JavaScript 访问特权函数。

unsafeWindow 在 2 个上下文之间建立了一座桥梁,如果不小心,可能会将某些 content 上下文函数暴露给 page JavaScript。

注意:在 GreaseMokey (& FireMonkey) 中,unsafeWindowwindow.wrappedJSObject 的别名。因此,使用两者没有区别。 unsafeWindow 的 TamperMonkey 和 ViolnetMonkey 实现是不同的。

在您的示例代码中,如果您不需要使用任何 GM 函数,您可以简单地将整个代码注入到 page 上下文中,而无需 unsafeWindow eg

const script = document.createElement('script');
script.textContent = '...code....';
document.body.appendChild(script);
script.remove(); // if you want,makes no difference