Ticket #164 (new defect)

Opened 1 year ago

Last modified 3 days ago

Object and array initialisers should use the global Object and Array bindings

Reported by: brendan Assigned to: lth
Type: defect Priority: major
Milestone: Component: Spec
Version: 3.1 Keywords:
Cc: jeffdyer, edwsmith, graydon, crock, chrispi, david-sarah@jacaranda.org

Description

These bindings, along with the other class-constructor-cum-type-name bindings, are immutable in ES4. That helps JSON integrity/security, but it is not enough: an inner scope could contain shadowing Object and Array bindings, and per ES3, these would be used ("as if by the expression new Object()"), and possibly you'd be hacked.

This is an incompatible change to ES3, but it seems like a necessary change for integrity. It might break clever but benign code, but I know of no examples on the public web. And it seems that not only Opera, but IE and Safari as well, do not follow the ES3 spec:

http://www.webappsec.org/lists/websecurity/archive/2007-08/msg00091.html

So this should break at most some odd Mozilla-only code that rebinds or shadows Object or Array in order to change what object and array initialisers construct -- if any such code exists.

This could start as a Spec bug and morph into a RefImpl? bug, or the other way around. I'm trying Spec first. Comments welcome.

/be

Attachments

Change History

Changed 1 year ago by lth

  • cc changed from jeffdyer, edwsmith, graydon, crock to jeffdyer, edwsmith, graydon, crock, chrispi

I agree that we should specify this tightly.

I also think that it is open to interpretation whether ES3 requires the evaluation of "new Array()", say, in the scope of the creation of the array literal or in another scope (typically the global scope). So I think it's open to interpretation whether shadowing actually plays a role. (Clearly Opera 9 does not even pick up any scoped value for "Array", and that seems wrong.)

Reading through ES3, the problem resurfaces also for "catch" blocks (a known bug that Pratap brought up) and letrec-style function expressions (I don't remember talking about this one).

There are plenty of other places that use the language "as if by new Array()" and "as if by new Object()", and the intent is clearly to pick up the global constructor if it is available, but otherwise scoping is not a problem there.

There's also evil language in the RegExp? library, since it requires "String.prototype.toUpperCase" to be called (says nothing about "original value of ...") using "as if" language. But that property is mutable.

Changed 1 year ago by brendan

See also

http://wiki.ecmascript.org/doku.php?id=clarification:which_prototype

which I wrote up by going through ES3 the hard way (find in Acrobat, looking for the cliched text patterns that either do, or do not, use the original value of Foo.prototype, etc.).

We are going to try locking down constructor bindings in JS1.8. See

https://bugzilla.mozilla.org/show_bug.cgi?id=376957

I think we should change ES3, 15.10.2.8 Atom, step 2 for "The internal helper function Canonicalize", as you propose: use the original value of String.prototype.toUpperCase. Especially if all browsers use that and do not reflect on the current value of that property!

/be

Changed 1 year ago by lth

  • priority changed from major to trivial
  • summary changed from Object and array initialisers should use the global Object and Array bindings to (Resolved) Object and array initialisers should use the global Object and Array bindings

None of the browsers pick up the changed value of toUpperCase.

Changed 3 days ago by David-Sarah Hopwood

  • cc changed from jeffdyer, edwsmith, graydon, crock, chrispi to jeffdyer, edwsmith, graydon, crock, chrispi, david-sarah@jacaranda.org
  • priority changed from trivial to major
  • version changed from 4 to 3.1
  • summary changed from (Resolved) Object and array initialisers should use the global Object and Array bindings to Object and array initialisers should use the global Object and Array bindings

This is intended to be fixed in ES3.1 (also for other globals such as *Error), but someone needs to check that all cases have been found.

Note: See TracTickets for help on using tickets.