使用脚本可以覆盖 Chrome 和 Firefox 中的 navigator.plugins 属性
Object.defineProperty(navigator, 'plugins', {
get: function() {
return [1, 2, 3, 4, 5];
},
});
所以基本上该属性是只读的,但是使用 getter 函数可以覆盖它。 (不是在控制台中,而是在脚本中)那么我如何测试该属性是否已被覆盖?
我读到有关接收应该返回 [native code] 的函数的 toString 属性
function isNative(fn) {
return (/\{\s*\[native code\]\s*\}/).test('' + fn);
}
现在我的问题是:如何测试 getter 是否被上面的 get:function()
.. 覆盖?
最佳答案
有一些技巧可以让您更接近确定函数是否被覆盖:
- 至少在 Chrome 中,
plugins
存在于Navigator.prototype
上,而不是window.navigator
上。如果代码在 Chrome 中运行并且该属性直接在navigator
上,则它已被覆盖。
const definitelyPatched = navigator.hasOwnProperty('plugins');
- 如果该属性已放在原型(prototype)上,请检查属性描述符是否与默认值匹配:它应该是可枚举和可配置的。如果不是,则已被覆盖。
const descriptor = Object.getOwnPropertyDescriptor(Navigator.prototype, 'plugins');
const definitelyPatched = descriptor.set || !descriptor.enumerable || descriptor.configurable;
- 结合以上内容,一个几乎万无一失的方法是使用
Function.prototype.toString
和.call< 绕过修补函数的自定义
:toString
/
const fn = function() {
return [1, 2, 3, 4, 5];
};
fn.toString = function() {
return '[native code]';
};
Object.defineProperty(Navigator.prototype, 'plugins',
{
get: fn,
});
const descriptor = Object.getOwnPropertyDescriptor(Navigator.prototype, 'plugins');
console.log(Function.prototype.toString.call(descriptor.get));
只有当 Function.prototype.toString
也被覆盖时才会失败,并且可以检测到此类修补 in multi-realm environments .
关于javascript - 测试导航器属性是否被 getter 函数覆盖的可靠方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65113798/