David Bruant wrote: > Tom Van Cutsem wrote: > > To my mind, the blame for the breakage lies with `Object.prototype` > > being mutated by the third-party script, not with property descriptors > > inheriting from Object.prototype. Thus, a fix for the breakage should > > address that directly, rather than tweaking the design of property > > descriptors, IMHO. > I agree. > > The first (security) decision any JavaScript application should make > would be to freeze all built-ins like SES [3][4] does. (In the future, > it could even make sense to add a CSP [5] directive for that) > If necessary, the application can first enhance the environment by > adding polyfills/libraries and such, but that's pretty much the only > thing that's acceptable to run before freezing everything.
Hey David and Tom. This is good advice for application authors, but I don't work at the application level; I write libraries. I don't want to freeze everything because I want to leave the environment open to monkey-patching and shimming by other libraries and the application authors. So this isn't an option for me. > "what if an attacker switches Array.prototype.push and Array.prototype.pop?" These are issues that are easy to address by using stored late-bound function references rather than methods and array-likes instead of true arrays. var push = Function.prototype.call.bind(Array.prototype.push), arrayLike = Object.create(null); arrayLike.length = 0; push(arrayLike, 'item-1'); As long as the environment is correct when my script initializes, I get all methods I need to use stored inside my library's closure. Freezing isn't needed. It's also possible to write around the `defineProperty` problem by converting the descriptor into a prototype-less object. However, I actually encountered some performance problems with this. I was able to improve the performance by only dropping the prototype when necessary (as long as `get`, `set`, `value` or `writable` haven't been added to `Object.prototype`, it's not necessary). However, as a matter of principle, my argument is that `Object.getOwnPropertyDescriptor` should, at the bare minimum, return a descriptor that can be known to work in `Object.defineProperty`. If `Object.defineProperty` doesn't accept it, then you `getOwnPropertyDescriptor` didn't really give me a valid descriptor. I think that this behavior (1) limits the creativity of developers to define properties like `Object.prototype.get`, (2) is a potential stumbling block, (3) has no real benefit -- really, there's not anything positive about this behavior, and (4) forces developers who want to support `Object.prototype.get` to add an extra layer of cleaning before using `defineProperty`. Nathan _______________________________________________ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss