After the comments from #1633 and #1634 and the referenced issues, I think it would be a good idea to create a runtime option that allows to whitelist the prototype of a given class.
Calling the template wit
template ({some: "input object"}, { allowedPrototypes: [
Test
] })
would allow a property to be resolved if the following is true.
parent[propertyName] === Test.prototype[propertyName] && Test.prototype.hasOwnProperty(propertyName)
I think it would be helpful when using custom classes in web-servers, because it is certainly not save to turn off prototype checks in such an environment.
I would like to have opinions about that.
One potential problem is that users will expect that adding B
to the allowed prototypes would work in this case:
class A { get a() { return 'a' } }
class B extends A {}
const parent = new B();
parent['a'] === B.prototype['a'] && B.prototype.hasOwnProperty('a') // => false
This isn't too bad, it just needs to be documented, but it would likely surprise quite a few people.
We could also check if superclasses are whitelisted, so you only need to whitelist "A" in order to get properties from "A" and "B" accepted.
The other way around is more difficult, because it required blacklisting all native classes, which may change over time.
@nknapp Would it be possible to use getPrototypeOf
and getOwnPropertyDescriptor
to see if the getter was defined. I'm not sure if this regresses to the issues that were already fixed or not.
class Example {
get hello() {
return 'world';
}
}
const obj = new Example();
console.log(obj.hello);
// "world"
console.log(Object.getOwnPropertyDescriptor(obj, 'hello'));
// undefined
console.log(Object.getOwnPropertyDescriptor(Object.getPrototypeOf(obj), 'hello'));
// { configurable: true, enumerable: false, get: function get hello() { return 'world'; }, set: undefined }
Most helpful comment
One potential problem is that users will expect that adding
B
to the allowed prototypes would work in this case:This isn't too bad, it just needs to be documented, but it would likely surprise quite a few people.