isPropertyEnumerable is going to stay broken?

classic Classic list List threaded Threaded
29 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Re: __proto__

Kris Zyp-2


__proto__ breaks abstraction boundaries in the language -- it's just
 
Hiding for the sake abstraction is more valuable than introspective visibility? I disagree, at least with JavaScript, IMHO JS's introspective nature is one of it's greatest strengths. Is there a precedence for this in other languages? Java is big on abstractions but inheritance is still introspectable (I realize that is not completely the same). And I believe that Self, the closest relative, makes the proto available throught .parent* property (I could be wrong about that).

security threat depends on the details of the environment: whether
 
Hasn't that security threat been evaluated by the years that this property has already been available?

 
Kris

_______________________________________________
Es4-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es4-discuss
Reply | Threaded
Open this post in threaded view
|

Re: __proto__

Brendan Eich-2
On Sep 11, 2007, at 1:47 PM, Kris Zyp wrote:

> __proto__ breaks abstraction boundaries in the language -- it's just
>
> Hiding for the sake abstraction is more valuable than introspective  
> visibility? I disagree, at least with JavaScript, IMHO JS's  
> introspective nature is one of it's greatest strengths. Is there a  
> precedence for this in other languages? Java is big on abstractions  
> but inheritance is still introspectable (I realize that is not  
> completely the same). And I believe that Self, the closest  
> relative, makes the proto available throught .parent* property (I  
> could be wrong about that).

Self has *-suffixed slots that constitute multiple prototypes per  
object. Yeah, JS is reflection-happy, or was. Some of it was  
distorted due to minimization (no activation reflection, so  
fun.caller) and that wasn't standardized. And ES1 intentionally  
censored activation object reflection, so much so that when closures  
were standardized in ES3, the bug where |this| inside a nested  
function does not match the outer function's |this| when the inner is  
called from the outer inadvertently bit.

Reflection is two-edged. It breaks abstraction, removes some theorems  
for free, and with mutation it can do a lot of damage (sometimes a  
good thing ;-).

A read-only __proto__ is hazardous for those factory closures that  
hide the created object's prototype. Without __proto__, you can't get  
at the prototype, which means you can enforce some integrity  
properties about names not being found rather than being found in the  
proto.

A read-write __proto__ is unthinkable (and in SpiderMonkey, complete  
with cycle detection :-P).

> security threat depends on the details of the environment: whether
>
> Hasn't that security threat been evaluated by the years that this  
> property has already been available?

It has, and while __proto__ has been used in some Mozilla PoCs over  
the years, it wasn't that big a deal. It was never exploited in the  
wild that we know of. But it added attack surface and it exacted a  
toll. I am not proposing it for ES4.

/be


_______________________________________________
Es4-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es4-discuss
Reply | Threaded
Open this post in threaded view
|

Re: __proto__

David Teller-3
In reply to this post by Kris Zyp-2
On Tue, 2007-09-11 at 13:47 -0700, Kris Zyp wrote:

>
>
>         __proto__ breaks abstraction boundaries in the language --
>         it's just
>  
> Hiding for the sake abstraction is more valuable than introspective
> visibility? I disagree, at least with JavaScript, IMHO JS's
> introspective nature is one of it's greatest strengths. Is there a
> precedence for this in other languages? Java is big on abstractions
> but inheritance is still introspectable (I realize that is not
> completely the same). And I believe that Self, the closest relative,
> makes the proto available throught .parent* property (I could be wrong
> about that).

I'd like a few cents on the subject of attacks: my research team is
working on security in the context of Firefox extensions. While
extensions are not the main focus of JavaScript, security decisions for
JS2 will be critical for them.

One thing many applications/extensions need is a way to actually hide
some information from other applications/extensions. While there's no
way to fully hide something from someone who can mingle with the VM, at
least, there should be some limits to JS2's introspections capabilities,
unless we want extensions to become vectors for
credit-card-number-stealing-attack .

I realise that a read-only __proto__ probably can't be used for this
type of attacks. But, well, I wanted this to be said before
"introspection rulez" becomes written in stone.

Cheers,
 David

--
David Teller ------------------------------------------
Security of Distributed Systems -----------------------
-- http://www.univ-orleans.fr/lifo/Members/David.Teller
----- Laboratoire d'Informatique Fondamentale d'Orleans

_______________________________________________
Es4-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es4-discuss
Reply | Threaded
Open this post in threaded view
|

Re: isPropertyEnumerable is going to stay broken?

Bob Clary-3
In reply to this post by Brendan Eich-2
In a fairly limited scan totaling about 3000 pages of the homepages of
33 top sites including those pages linked from the homepages I found
three occurrences of essentially the same script:

<http://kaden.yahoo.co.jp/js/connection/connection-min.js>
<http://cn.yimg.com/i/js/ycnconn.js>
<http://cn.yimg.com/ncp/fashion/js3/ycnconn.js>

where propertyIsEnumerable is used incorrectly (as a property rather
than as a function) but which appears to have intended to get the "don't
search prototype" behavior.

Due to the nature of the scan (using the narcissus parser in the
browser), the scan was fairly slow. I can use a different approach and
cover more pages if there is more interest. If not, I'll let this rest here.


Brendan Eich wrote:

> On Sep 8, 2007, at 10:06 PM, Garrett Smith wrote:
>
>> https://bugzilla.mozilla.org/show_bug.cgi?id=57048
>>
>> In this bug, dated 2000, Brendan and David agreed that
>> isPropertyEnumerable should check the prototype chain.
>
> That was a long time ago, and while David Flanagan carries a lot of
> weight with many folks, he was not on ECMA TC39 TG1, and no one on the
> group changed the spec.
>
> A lot of water under the bridge since then.
>
>> It should not backwards compatibility,
>
> Famous last words. :-)
>
> We try to spider the web (Alexa top 1000 and the like) looking for
> counterexamples to such claims, and if we fail to find any, or better,
> we find instances of confusion where the incompatible fix is assumed
> (i.e., the JS author thought the spec worked the way we want to change
> it to work), then we have some confidence, but not much more, in favor
> of making an incompatible change. In general. In this case, no one has
> done such a scan. I'll see if I can get one started.
>
>> but such functionality in the
>> language seems necessary. How to check enumerable attribute, including
>> the prototype chain?
>
> Either reflect the __proto__ (read-only, please) property as some
> implementations do, or hardcode the prototype structure and code your
> propertyIsEnumerable tests accordingly.
>
> /be
>

_______________________________________________
Es4-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es4-discuss
Reply | Threaded
Open this post in threaded view
|

Re: isPropertyEnumerable is going to stay broken?

Garrett Smith
 YUI Connection Manager

               for(var prop in this._http_header){
                       if(this._http_header.propertyIsEnumerable){
                               o.conn.setRequestHeader(prop,
this._http_header[prop]);
                       }
               }

The conditional check will have the effect of filtering out all
browsers which don't support propertyIsEnumerable (effectively
breaking Safari 2).

Regardless, the proposed change to propertyIsEnumerable will have no
effect on the Connection Manager.

There is something called Moodle that seems to use propertyIsEnumerable.

propertyIsEnumerable is a seldom used method.

Have to let implementations know to change support of this feature (if
the change happens).
Flash, all browsers, Apple (konfabulator, OS), Nokia, et c.

The change might even be widely supported until 2012 for a programmer
to use, and then programmers will have to test not for
propertyIsEnumerable, but for which one.


if( "propertyIsEnumerable" in Object.prototype ) {
// Which propertyIsEnumerable do we have?
   if( isPropertyIsEnumearablePrototypeEnabled() ) {
       if( obj.propertyIsEnumerable( prop ) ) {

      }
   }
}

var isPropertyIsEnumearablePrototypeEnabled = function() {
   var o = function(){};
   var garbage = "~~~__0*";
   o.prototype[ garbage ] = true;
   var supported = o.propertyIsEnumerable( garbage );
   return supported;
}

Garrett


On 9/16/07, Bob Clary <[hidden email]> wrote:

> In a fairly limited scan totaling about 3000 pages of the homepages of
> 33 top sites including those pages linked from the homepages I found
> three occurrences of essentially the same script:
>
> <http://kaden.yahoo.co.jp/js/connection/connection-min.js>
> <http://cn.yimg.com/i/js/ycnconn.js>
> <http://cn.yimg.com/ncp/fashion/js3/ycnconn.js>
>
> where propertyIsEnumerable is used incorrectly (as a property rather
> than as a function) but which appears to have intended to get the "don't
> search prototype" behavior.
>
> Due to the nature of the scan (using the narcissus parser in the
> browser), the scan was fairly slow. I can use a different approach and
> cover more pages if there is more interest. If not, I'll let this rest here.
>
>
> Brendan Eich wrote:
> > On Sep 8, 2007, at 10:06 PM, Garrett Smith wrote:
> >
> >> https://bugzilla.mozilla.org/show_bug.cgi?id=57048
> >>
> >> In this bug, dated 2000, Brendan and David agreed that
> >> isPropertyEnumerable should check the prototype chain.
> >
> > That was a long time ago, and while David Flanagan carries a lot of
> > weight with many folks, he was not on ECMA TC39 TG1, and no one on the
> > group changed the spec.
> >
> > A lot of water under the bridge since then.
> >
> >> It should not backwards compatibility,
> >
> > Famous last words. :-)
> >
> > We try to spider the web (Alexa top 1000 and the like) looking for
> > counterexamples to such claims, and if we fail to find any, or better,
> > we find instances of confusion where the incompatible fix is assumed
> > (i.e., the JS author thought the spec worked the way we want to change
> > it to work), then we have some confidence, but not much more, in favor
> > of making an incompatible change. In general. In this case, no one has
> > done such a scan. I'll see if I can get one started.
> >
> >> but such functionality in the
> >> language seems necessary. How to check enumerable attribute, including
> >> the prototype chain?
> >
> > Either reflect the __proto__ (read-only, please) property as some
> > implementations do, or hardcode the prototype structure and code your
> > propertyIsEnumerable tests accordingly.
> >
> > /be
> >
>
> _______________________________________________
> Es4-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es4-discuss
>


--
Programming is a collaborative art.
_______________________________________________
Es4-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es4-discuss
Reply | Threaded
Open this post in threaded view
|

Re: __proto__

Garrett Smith
In reply to this post by Lars T Hansen-2
On 9/11/07, Lars T Hansen <[hidden email]> wrote:

> On the one hand, __proto__ is another potential security hole, and it
> prevents implementations from sharing prototype objects among multiple
> documents -- the link may be read-only but the object isn't.  Function
> B called from function A with object O may hack O.__proto__ and A can
> do nothing about it; suddenly all O-like objects in the system act
> differently.
>
> On the other hand, Constructor.prototype is generally available for
> any Constructor, so it's hard to see what the real damage is -- it's
> not obviously worse than some other aspects of the language.
>

What I've found is that it's always giving wrong constructor property
with inheritance chains.

A <-- B <-- C
c = (new C).constructor;// A

So to do this, I can use a chaining technique to hardcode the
inheritance structure reading __proto__ or using hand-rolled
constructor chaining, but then that requires that clients who try to
get the constructor build their inheritance with the same approach
that I do, and get an enumerable constructor property on their class
as a side effect.

The chaining technique was published many years ago by Kevin Lindsey
and used by some popular libraries like YUI.

How about a constructor property on the function instance?

> On the third hand, some implementations may have specialized objects
> for which no Constructor is available and for whom keeping
> [[Prototype]] unavailable is desirable.  Similarly, some toolkits may
> have private prototype objects that are not available to client code
> because the constructor is hidden in a lexical scope (ES3) or
> package/namespace (ES4).
>
Could they make these private for their class? Is [[Get]] modified to
exclude private members in ES4?

How is prototype inheritance different than shadowing static members
in Java? Are private static members a security problem in Java?

Here's an example showing how to use __proto__ to get the constructor.
http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Guide:Property_Inheritance_Revisited:Determining_Instance_Relationships

__proto__ makes the language more transparent.


> Introspection is great, but it assumes a lot about how trust works in
> the environment.
>
> --lars
>
>
> On 9/11/07, Kris Zyp <[hidden email]> wrote:
> > > The alternative above would standardize read-only __proto__, which  would
> > > make that property no longer implementation-specific. But of  course we
> > > have no proposal to do that.
> > I realize this wasn't really the main subject... but could the __proto__
> > property be defined in the spec (as readonly)? I would love to see that
> > property standardized.
> > Kris
> >
> > _______________________________________________
> > Es4-discuss mailing list
> > [hidden email]
> > https://mail.mozilla.org/listinfo/es4-discuss
> >
> _______________________________________________
> Es4-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es4-discuss
>


--
Programming is a collaborative art.


--
Programming is a collaborative art.
_______________________________________________
Es4-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es4-discuss
Reply | Threaded
Open this post in threaded view
|

Re: __proto__

liorean
On 22/09/2007, Garrett Smith <[hidden email]> wrote:

> What I've found is that it's always giving wrong constructor property
> with inheritance chains.
>
> A <-- B <-- C
> c = (new C).constructor;// A
>
> So to do this, I can use a chaining technique to hardcode the
> inheritance structure reading __proto__ or using hand-rolled
> constructor chaining, but then that requires that clients who try to
> get the constructor build their inheritance with the same approach
> that I do, and get an enumerable constructor property on their class
> as a side effect.

You get that if you do the following:

    function A(){}
    function B(){}
    B.prototype=new A;
    function C(){}
    C.prototype=new B;

Because if you do that, you replace the prototype containing the
original constructor property  (e.g. a reference back to the function
C) with an instance of another constructor (e.g. B), but that instance
doesn't have the constructor property that the original prototype had.
If you want to keep the constructor properties, you need to do that
manually. (With the obvious result that then the constructor property
will be enumerable. Which can be changed through adding a call on
propertyIsEnumerable in ES4.)

> The chaining technique was published many years ago by Kevin Lindsey
> and used by some popular libraries like YUI.

It's actually far older than that, and I think the Netscape JavaScript
guides and references even contained a crash course in this. I think
it's mentioned in my oldest JavaScript books, published around 1996.

> How about a constructor property on the function instance?

Wouldn't help, the constructor property would have to be set on the
object the constructor builds.

Which could be done, of course, it should be a simple thing to add
that in the algorithm for [[Construct]]. But then we have the question
of what to do with constructors that return other objects than that
set up by steps 1 through 5 of the [[Construct]] algorithm. A
constructor can return other objects, you know. You'd have to decide
whether this property should be set up prior to step 6 in the
algorithm or subsequent to step 7. If prior, only the original object
that was created in step 1 gets it, if subsequent, return values get
it even if they are not the same as the original object.


Actually, I think this would be a nice and simple fix to ES3 that
probably wouldn't hurt much code out there.
--
David "liorean" Andersson
_______________________________________________
Es4-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es4-discuss
Reply | Threaded
Open this post in threaded view
|

Re: isPropertyEnumerable is going to stay broken?

Garrett Smith
In reply to this post by Brendan Eich-2
On 9/10/07, Brendan Eich <[hidden email]> wrote:
> On Sep 10, 2007, at 2:21 PM, Garrett Smith wrote:

> > The fact that the method
> > was called propertyIsEnumerable instead of isPropertyEnumerable is not
> > great, but the way propertyIsEnumerable is designed is confusing to
> > developers.
>
> I've never heard that complaint directly, or in a
> bugzilla.mozilla.org report. Can you cite complaints anywhere on the
> web? I believe you, but it would be good to have evidence.
>
Web search:
http://livedocs.adobe.com/flashlite/2/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00000728.html
http://www.adobe.com/livedocs/flash/8/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00002578.html

Apparently flash actually has a custom "isPropertyEnumerable" method.
It's on Adobe's website. I don't do Flash, so I can't say much about
it. It looks like a straight rename method, though.

This guy wants a rename, too:
http://lists.macosforge.org/pipermail/webkit-reviews/2005-December/002269.html

isPropertyEnumerable and/or propertyIsEnumerable could return true if
an object can be enumerated in a for-in loop, and  check the prototype
chain.

Given the above change, the old (current) behavior could be achieved with:
r.propertyIsEnumerable( p ) && r.hasOwnProperty( p );

The change would allow for 4 different possibilities of r[ p ]


Garrett

>
> /be
>


--
Programming is a collaborative art.
_______________________________________________
Es4-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es4-discuss
Reply | Threaded
Open this post in threaded view
|

Re: __proto__

P T Withington
In reply to this post by liorean
On 2007-09-22, at 17:52 EDT, liorean wrote:

> Which could be done, of course, it should be a simple thing to add
> that in the algorithm for [[Construct]]. But then we have the question
> of what to do with constructors that return other objects than that
> set up by steps 1 through 5 of the [[Construct]] algorithm. A
> constructor can return other objects, you know. You'd have to decide
> whether this property should be set up prior to step 6 in the
> algorithm or subsequent to step 7. If prior, only the original object
> that was created in step 1 gets it, if subsequent, return values get
> it even if they are not the same as the original object.

Dylan has a rule that the constructor must return an object that is a  
subtype of the constructor.  If that were enforced, I would see no  
reason to reset the constructor property of the returned object.

> Actually, I think this would be a nice and simple fix to ES3 that
> probably wouldn't hurt much code out there.

Agreed.  As I mentioned elsewhere in this thread, we do this manually  
in our framework for now.

_______________________________________________
Es4-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es4-discuss
12