修改浏览器指纹属性时,如何让属性访问触发TypeError?
问题:修改浏览器指纹属性后如何保留原TypeError触发行为?
我正在开发一款修改浏览器指纹的工具,使用Object.defineProperty修改属性值后,访问该属性不会像原对象那样触发TypeError,这一特性会被安全系统识别出修改行为。
我的修改方式如下(Screen仅为示例,需支持多个属性的通用解决方案):
const proto = Screen.prototype; const propName = 'availHeight'; const descriptors = Object.getOwnPropertyDescriptor(Screen.prototype, 'availHeight'); const overrideDescriptors = { get: () => 1000 } Object.defineProperty(proto, propName, { ...descriptors, ...overrideDescriptors });
原生行为(预期):
直接访问原型属性会抛出错误:
typeof Screen.prototype.availHeight; // Uncaught TypeError: Illegal invocation at <anonymous>:1:25
修改后的实际行为:
访问原型属性返回自定义值,无错误:
typeof Screen.prototype.availHeight; // 'number'
请问如何调整代码,才能让属性访问检查和原属性一致,触发TypeError?
解决方案
核心问题是原生属性的getter会校验调用时的this指向——只有当this是对应类的实例时才正常返回,否则抛出Illegal invocation错误。而你用箭头函数定义的getter会丢失this绑定,导致校验失效。
通用修改方案
修改getter函数为普通函数,在内部添加this实例校验,非实例时抛出与原生一致的错误:
const proto = Screen.prototype; const propName = 'availHeight'; const descriptors = Object.getOwnPropertyDescriptor(proto, propName); const overrideDescriptors = { // 使用普通函数保留this绑定 get() { // 校验this是否为当前类的实例 if (!(this instanceof proto.constructor)) { throw new TypeError('Illegal invocation'); } // 实例访问时返回自定义值 return 1000; } }; Object.defineProperty(proto, propName, { ...descriptors, ...overrideDescriptors });
批量处理工具函数
如果需要修改多个属性,可以封装通用工具函数简化操作:
function overrideFingerprintProperty(proto, propName, customValue) { const descriptors = Object.getOwnPropertyDescriptor(proto, propName); // 仅处理存在getter的属性 if (!descriptors || typeof descriptors.get !== 'function') return; Object.defineProperty(proto, propName, { ...descriptors, get() { // 校验this是否为目标类的实例 if (!(this instanceof proto.constructor)) { throw new TypeError('Illegal invocation'); } return customValue; } }); } // 使用示例 overrideFingerprintProperty(Screen.prototype, 'availHeight', 1000); overrideFingerprintProperty(Screen.prototype, 'availWidth', 1920); overrideFingerprintProperty(Navigator.prototype, 'userAgent', 'Mozilla/5.0 ...');
验证效果
- 直接访问原型属性:
Screen.prototype.availHeight→ 抛出TypeError: Illegal invocation,与原生一致 - 通过实例访问:
window.screen.availHeight→ 返回自定义值1000,实现指纹修改需求
内容的提问来源于stack exchange,提问作者Cosmo773
相关产品推荐
相关产品推荐

