通过使 `Function.prototype[Symbol.hasInstance]` 不可写和不可配置来防止什么样的“篡改”?

问题描述 投票:0回答:1

ECMAScript 2015 官方规范

Symbol.hasInstance
says(ECMA-262 6th Ed. §19.2.3.6):

[

Symbol.hasInstance
属性]不可写且不可配置,以防止篡改,篡改可用于全局公开绑定函数的目标函数。

现在,即使是不可写和不可配置的属性也可以用

Object.defineProperty
覆盖,事实上,如果您尝试覆盖
Symbol.hasInstance
以始终返回 true,那么它就会这样做。

虽然我不明白这句话。

大概,当您覆盖目标的

Symbol.hasInstance
以返回 true 时,全局函数可能会被暴露的情况是绑定函数的情况。当然它会返回 false,因为目标将其原型交换到绑定函数上,因此绑定函数不是目标的实例。另外,根据我的最佳理解,我相信它最终会出现在全局范围内的原因是因为绑定函数没有原型,因此实际上不能成为目标函数的实例,因此如果您强制将其作为实例,则目标的原型被强制作用于不存在的绑定原型上,最终会失败并将目标的
this
置于全局范围内。但是,即使我将其设置为返回 true,我仍然无法让它在全局范围内公开目标。

注意,这是我试图做的事情,以更好地理解 JavaScript 的内部工作原理。在实际应用中,我不想在全球范围内公开目标。

我已经尝试了好几个小时摆弄绑定函数的一系列代码片段,并且

Symbol.hasInstance
返回 true 但无济于事。我无法让它在全球范围内公开目标的功能和数据。如果有人更好地理解这一点,我们将不胜感激。我碰壁了。

javascript ecmascript-6 instanceof function-binding
1个回答
3
投票

让我们澄清一下,您正在谈论规范的第 19.2.3.6 部分,这是

Function.prototype[Symbol.hasInstance]
的规范。

最新版本规范中的文本是:

此属性不可写且不可配置,以防止可用于全局公开绑定函数的目标函数的篡改。

这说明你不能这样做:

// A malicious library loads here and overrides the function.
(function(){
  Object.defineProperty(Function.prototype, Symbol.hasInstance, {
    value: function(instance){
      const context = this;

      // Here, `this === SomeClass`
    },
  });
}();

// Some library loads here.
(function(){
  function SomeClass(){}

  const BoundClass = SomeClass.bind(null);

  var tmp = {} instanceof BoundClass;
})();

因此,在这个示例中,如果属性是

configurable: true
,则恶意库将能够访问
SomeClass
,否则该属性将是完全私有的,并且范围在 IIFE 内。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.