Nuking misleading properties in `Object.getOwnPropertyDescriptor`

Mark S. Miller erights at google.com
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.

[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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20130313/828837f5/attachment.html>


More information about the es-discuss mailing list