我正试图开发一个Firefox扩展,通过对抗用于用户跟踪目的的浏览器指纹来保护用户安全。
许多(如果不是所有的话)指纹技术包括记录navigator.plugins
、navigator.oscpu
、navigator.platform
的内容、屏幕分辨率、窗口工具栏高度等。扩展的想法由两部分组成——第一部分是随机过滤和置换插件及其mime类型,并在用于跟踪的其他变量中引入随机性;第二是隔离网页,防止其重复使用以前隐藏的信息,如.sol
-cookie,利用伪造的E-Tag
s或任何尚未发现的信息。
这两种方法都需要在特权navigator
、screen
、location
对象的不可配置属性上重新实现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
结束,在那里完成了实际的对象修改。
因此,问题是:
- 是否可以为页面内容沙盒完全重新定义
location
、navigator
、screen
对象,用一些模拟代理替换它们,由我的扩展控制 - 或者,是否可以重新定义上述对象的不可配置属性
- 或者,是否可以从chrome JavaScript调用
js::NativeDefineProperty
- 或者(不太可取),是否可以实现二进制插件,将
js::NativeDefineProperty
作为服务公开给chrome
更新:我在Mozilla IRC遇到一个问题,位置重写与隐私有何关系。就目前而言,所有处于私人浏览模式的窗口都共享相同的cookie、存储等,所以即使在私人模式下,如果你不经常重置,你仍然可以被跟踪。多久一次是一个问题——理想情况下,你应该在每个访问过的网站后重置,因为每个网站都会标记你。如果能够调整私有模式的粒度,比如将私有窗口或选项卡彼此分离,那就太酷了。
我想用某种标签唯一的长随机标签来标记所有的URL——所以在两个单独的私有标签中打开的http://example.com/foo
变成了http://example.com.AYZYXP/foo
和http://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的一个选项卡中更改用户代理?