[[SetInheritance]] (was: General comments response (was Re: ES6 Rev13 Review: MOP-refactoring, symbols, proxies, Reflect module))
On Monday, December 31, 2012, Tom Van Cutsem wrote:
That said, I think this issue is orthogonal to our choice of whether or not to expose "setPrototypeOf" as part of the MOP. Even if we do expose it, any sandbox that wants to take away the ability the set the prototype can simply poison Reflect.setPrototypeOf in addition to deleting Object.prototype.proto.
Ive realized this is actually a potentially serious flaw with the module
system with to how the builtin modules expose features. If you
introduce Reflect.setPrototypeOf (or more generally, anything exposed
as an export of
a system module) there is no way for something like SES (user level) to
remove access to it. There's no way to monkey patch these things or remove
them or add new features to them because the modules aren't externally
mutable. delete Reflect.setPrototypeOf
is not currently an option.
On Dec 31, 2012, at 7:28 AM, Brandon Benvie wrote:
On Monday, December 31, 2012, Tom Van Cutsem wrote: That said, I think this issue is orthogonal to our choice of whether or not to expose "setPrototypeOf" as part of the MOP. Even if we do expose it, any sandbox that wants to take away the ability the set the prototype can simply poison Reflect.setPrototypeOf in addition to deleting Object.prototype.proto.
Ive realized this is actually a potentially serious flaw with the module system with to how the builtin modules expose features. If you introduce Reflect.setPrototypeOf (or more generally, anything exposed as an export of a system module) there is no way for something like SES (user level) to remove access to it. There's no way to monkey patch these things or remove them or add new features to them because the modules aren't externally mutable.
delete Reflect.setPrototypeOf
is not currently an option.
I'll leave it to Dave or Sam to elaborate, but I don't think this is correct. My understanding, is that such censoring can be accomplished by configuring a module loader to return an alternative implementation of the "@Reflect" (or however it is identified) which could either not export Reflect.setPrototypeOf or export an alternative implementation.
2012/12/30 Allen Wirfs-Brock <allen at wirfs-brock.com>
Ok. I did a search for [[SetInheritance]] in the Rev13 draft and the only place this method was called was from Reflect.setPrototypeOf and the Proxy "setPrototypeOf" trap default. That's why I thought it could easily be removed. I now see the note that appendix B3.1 (specifying proto) is not yet up-to-date. Probably when it's updated, this part of the spec will also call [[SetInheritance]].
It seems there are two routes we can take a) Introduce a "setPrototypeOf" trap (as currently specified), with the invariant check that the new prototype must match that of the target if setPrototypeOf returns true (a return value of "false" would mean the proxy rejected the prototype change).
b) Not treat proto as a magical property on proxies, and get rid of the "setPrototypeOf" trap. This implies that aProxy.proto = val just triggers the "set" trap. This delegates the choice of whether to treat proto as magical or not to every individual proxy handler.
Reflect.setPrototypeOf is not essential and simply there to provide a point
I agree that if we take choice (a) (i.e. introduce a "setPrototypeOf" trap) then we should also have the corresponding Reflect.setPrototypeOf primitive.
Yep.
Agreed. Although we should make an effort to make it easy for sandboxes/dialects to remove the feature from the language.
That said, I think this issue is orthogonal to our choice of whether or not to expose "setPrototypeOf" as part of the MOP. Even if we do expose it, any sandbox that wants to take away the ability the set the prototype can simply poison Reflect.setPrototypeOf in addition to deleting Object.prototype.proto.