denoland / deno

A modern runtime for JavaScript and TypeScript.
https://deno.com
MIT License
96.42k stars 5.33k forks source link

WebIDL API class constructor's incorrectly construct superclasses #11718

Open ghost opened 3 years ago

ghost commented 3 years ago

Many ES builtins, and nearly all WebIDL APIs do not construct a class's parent class by looking up a dynamic prototype. The problem is... ECMAScript's super keyword does exactly that.

Reproduction code:

Reflect.setPrototypeOf(AbortSignal, null);
console.log(AbortSignal.abort());

Tested in Firefox and Deno, Firefox's constructor is unaffected, whereas Deno's crashes because super no longer works.

(Furthermore, this can be used to steal the internal illegalConstructorKey symbol, by using a user-defined constructor, allowing code to go willy-nilly, constructing everything, e.g. Window 😉)

ghost commented 3 years ago

This was also mentioned in a could-be ES proposal, with some workarounds: https://github.com/littledan/proposal-new-initialize. (I believe that JSDOM already has infrastructure for handling this and linking prototypes correctly? Maybe something could be taken from there?)

Edit: there doesn't seem to be workaround, while maintaining private fields. An alternative could be for WebIDL classes to maintain WeakMaps which mapping class instances to their data, replacing private field access with WeakMap lookups, and super to be replaced with Reflect.construct?

stale[bot] commented 3 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days if no further activity occurs. Thank you for your contributions.