如何使用Firefox扩展模拟特定页面的“位置”、“导航器”和好友

How to mock `location`, `navigator` and friends for specific page using Firefox extension?

本文关键字:位置 导航 好友 导航器 扩展 Firefox 何使用 模拟      更新时间:2023-09-26

我正试图开发一个Firefox扩展,通过对抗用于用户跟踪目的的浏览器指纹来保护用户安全。

许多(如果不是所有的话)指纹技术包括记录navigator.pluginsnavigator.oscpunavigator.platform的内容、屏幕分辨率、窗口工具栏高度等。扩展的想法由两部分组成——第一部分是随机过滤和置换插件及其mime类型,并在用于跟踪的其他变量中引入随机性;第二是隔离网页,防止其重复使用以前隐藏的信息,如.sol-cookie,利用伪造的E-Tags或任何尚未发现的信息。

这两种方法都需要在特权navigatorscreenlocation对象的不可配置属性上重新实现getter,而这正是我陷入困境的地方。

例如,在浏览器控制台中输入以下简单的代码是不起作用的:

Object.defineProperty(getBrowser().contentWindow.location, 'href', {
    get: function() {
        return 'foobar';
    }
});

它不会产生任何错误,但也不会重新定义特性。此外,由于某种原因,它返回了location对象的当前值——这是我对Object.defineProperty没有期望的。

location.wrappedJSObject替换location会使浏览器吐出TypeError: can't redefine non-configurable property 'href',这与非特权代码将抛出的内容相同。

我试着追踪当你打电话给Object.defineProperty时会发生什么。它似乎从js::obj_defineProperty()开始,然后到js::StandardDefineProperty,它依次进行几次检查,然后下降到js::DefinePropertyOnObject,它有大量的检查,我还不完全理解,最后到js::NativeDefineProperty结束,在那里完成了实际的对象修改。

因此,问题是:

  1. 是否可以为页面内容沙盒完全重新定义locationnavigatorscreen对象,用一些模拟代理替换它们,由我的扩展控制
  2. 或者,是否可以重新定义上述对象的不可配置属性
  3. 或者,是否可以从chrome JavaScript调用js::NativeDefineProperty
  4. 或者(不太可取),是否可以实现二进制插件,将js::NativeDefineProperty作为服务公开给chrome

更新:我在Mozilla IRC遇到一个问题,位置重写与隐私有何关系。就目前而言,所有处于私人浏览模式的窗口都共享相同的cookie、存储等,所以即使在私人模式下,如果你不经常重置,你仍然可以被跟踪。多久一次是一个问题——理想情况下,你应该在每个访问过的网站后重置,因为每个网站都会标记你。如果能够调整私有模式的粒度,比如将私有窗口或选项卡彼此分离,那就太酷了。

我想用某种标签唯一的长随机标签来标记所有的URL——所以在两个单独的私有标签中打开的http://example.com/foo变成了http://example.com.AYZYXP/foohttp://example.com.QUSOFX/foo。从浏览器的角度来看,这是两个不同的域名,有自己的缓存规则、cookie、DOM存储、IndexedDB、FlashPlayer存在或其他任何东西。从网页的角度来看,有必要保持两个标签都是http://example.com/foo的印象,因为暴露标签会违背标记的想法——这就是为什么我需要重写位置。

可能有一种方法可以进行一次更改,浏览器会将其发送到所有内容,window.navigator.blah的javascript代码会返回您覆盖的值。如果我发现那样的东西,我会睁大眼睛的。

以下是XPCOM参考:https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface

我相信,如果你探索所有这些,你会发现一些可以覆盖的东西。

但下面是一个解决方案,您可以附加一个观察者

我不确定你是否设置了请求或响应头,window.navigator.blah的javascript是否会返回什么,但值得一试,复制粘贴代码。看看吧。

您所做的是为http-on-modify-request设置一个观察器(或者其他人可以在此处查看其他观察器:MDN::observer Notifications-HTTP Requests)

然后在观察器的处理程序中,您使用setRequestHeader等进行修改,如果您为http-on-examine-response进行观察器,甚至可以使用setResponseHeader

请参阅本主题,此处的示例代码仅针对第一个选项卡欺骗用户代理:如何在Firefox的一个选项卡中更改用户代理?