Hi, This is an attempt to list and discuss how threats of a mutable __proto__ can be prevented and how it is different in the data and accessor property cases.
## One frame Assuming code from 2 parties are running in the same "frame" (one set of built-ins) ----- var o = Object.create(Object.freeze({a:1})); o.a = 1; // and may assume it will keep being this way unless shadowing 'a' // passing o to malicious code: o.__proto__ = {a:2}; // back in normal code: o.a; // 2. hey! WTF! ----- ### How to prevent this? #### delete Object.prototype.__proto__ Unconditionnally prevents using __proto__ (setting and getting!) for everyone (even those who would have "legitimate" use cases). In case the property is a configurable accessor, the prototype setting capability can be removed, getting can be left and the property can be made non-configurable. The party who does this can keep the prototype setting capability to herself and share with whoever she trusts. It is also possible to share an attenuated version of the capability (allowing to change the prototype of some objects and not some others) #### non-extensible as protection Object.preventExtensions(o) would protect just o. This technique and the previous one could be used together. ## Several Object.prototype.__proto__ in the same "Vat" (synchronous access to several Object.prototype.__proto__) ### Startup If there are several Object.prototype at startup, the work to secure all of them is just the work to secure one (delete or finer-grained version of the accessor case), but repeated. ### Dynamic creation of Object.prototype.__proto__ instances If a new Object.prototype.__proto__ becomes reachable (by opening a same-origin iframe, for instance), if the parent can run before any script in the child, she can do whatever she wants: - deleting childframe.Object.prototype.__proto__ if she wants to defend against what the child could do - redefine any built-ins to attack the child. If the child can run some code before the parent is notified that a new Object.prototype.__proto__ is reachable, she can protect herself against the parent or attack (redefine any built-in) of her parent. ## Questions * What are all the cases in nowadays browsers where a new Object.prototype.__proto__ can be dynamically created? (The only one I can think of is same-domain iframe, but I think there exists some weird rules for one frame to access another by changing its own domain to a subdomain, or something like this) * For each case, who has access to the other first? The creater or the creature? * One difference that is made in the accessor case is that if one party runs before the other, then this first one can keep a reference to the setter. Does this increase the already existing attack surface? David _______________________________________________ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss