Nuking misleading properties in `Object.getOwnPropertyDescriptor`

Mark S. Miller erights at
Wed Mar 13 08:36:22 PDT 2013

The one qualification everyone should be aware of is that if they simply
freeze these themselves, rather than using the tamper-proofing abstractions
defined by SES[1][2], then they will suffer from the override mistake[3]
and conventional code such as the following will break:

  function Point(x, y) {
    this.x = x;
    this.y = y;
  Point.prototype.toString = function() {
    return '<' + x + ',' + y + '>';

This normal looking assignment to Point.prototype.toString fails because
Point.prototype inherits from Object.prototype, on which toString is a
non-writable non-configurable data property.


On Wed, Mar 13, 2013 at 7:18 AM, David Bruant <bruant.d at> wrote:

>  Le 12/03/2013 16:45, Tom Van Cutsem a écrit :
> Hi Nathan,
>  2013/3/10 Nathan Wall <nathan.wall at>
>> Given that `defineProperty` uses properties on the prototype of the
>> descriptor[1] and `getOwnPropertyDescriptor` returns an object which
>> inherits from `Object.prototype`, the following use-case is volatile:
>>     function copy(from, to) {
>>         for (let name of Object.getOwnPropertyNames(from))
>>             Object.defineProperty(to, name,
>>                 Object.getOwnPropertyDescriptor(from, name));
>>     }
>> If a third party script happens to add `get`, `set`, or `value` to
>> `Object.prototype` the `copy` function breaks.
>  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.
> As Object.prototype-jacking threats are discussed more and more recently,
> I'd like to take a step back and "meta-discuss" JavaScript threats.
> Currently, by default, any script that run can mutate the environment it
> is executed in (it can be fixed by sandboxing with things like Caja [1] and
> soon the module loader API used with proxies [2], but even then, there
> could be leaks of native built-ins).
> 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.
> Given that freezing all built-ins (after polyfills) is a reasonable thing
> to do, I think JavaScript threat should be considered serious only if
> applicable assuming the environment is already frozen.
> It naturally rules out threats related to property descriptors inheriting
> from Object.prototype or anything looking like "what if an attacker
> switches Array.prototype.push and Array.prototype.pop?"
> David
> [1]
> [2]
> [3]
> [4]
> [5]

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the es-discuss mailing list