Nuking misleading properties in `Object.getOwnPropertyDescriptor`

Andrea Giammarchi andrea.giammarchi at gmail.com
Thu Mar 14 10:02:32 PDT 2013


this is an excellent "Point" Mark, I wish I mentioned  this earlier in
redefine.js

For already panicing developers sake, the problem addressed by Mark can be
easily solved going explicitly over the property definition so that this
won't work:

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

alert(new Point(1, 2)); // [object Object]

but this will:
Object.defineProperty(
  Point.prototype,
  'toString', {value:
  function() {
    return '<' + this.x + ',' + this.y + '>';
  }
});

alert(new Point(1, 2)); // <1,2>

br




On Wed, Mar 13, 2013 at 8:36 AM, Mark S. Miller <erights at google.com> wrote:

> 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.
>
> [1]
> https://code.google.com/p/google-caja/source/browse/trunk/src/com/google/caja/ses/repairES5.js#466
> [2]
> https://code.google.com/p/google-caja/source/browse/trunk/src/com/google/caja/ses/startSES.js#869
> [3]
> http://wiki.ecmascript.org/doku.php?id=strawman:fixing_override_mistake
>
>
>
>
> On Wed, Mar 13, 2013 at 7:18 AM, David Bruant <bruant.d at gmail.com> wrote:
>
>>  Le 12/03/2013 16:45, Tom Van Cutsem a écrit :
>>
>> Hi Nathan,
>>
>>  2013/3/10 Nathan Wall <nathan.wall at live.com>
>>
>>> 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] http://code.google.com/p/google-caja/
>> [2] http://wiki.ecmascript.org/doku.php?id=harmony:module_loaders
>> [3] http://code.google.com/p/es-lab/wiki/SecureEcmaScript
>> [4]
>> http://code.google.com/p/es-lab/source/browse/#svn%2Ftrunk%2Fsrc%2Fses
>> [5]
>> https://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html
>>
>
>
>
> --
>     Cheers,
>     --MarkM
>
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20130314/158d2a2d/attachment.html>


More information about the es-discuss mailing list