Kevin Reid (2013-08-29T20:39:30.000Z)
On Thu, Aug 29, 2013 at 12:56 PM, Allen Wirfs-Brock
<allen at wirfs-brock.com>wrote:

> On Aug 29, 2013, at 10:51 AM, Kevin Reid wrote:
>
> This is a hazardous change for SES-style security. For example, I've just
> taken a quick look at our (Caja) codebase and found a place where
> Array.prototype.slice.call(foo) is used to obtain a “no funny business”
> array (i.e. doesn't have side effects when you read it) and another where
> it's used to obtain an array which must be in the caller's realm. These
> would be easy enough to replace with a more explicit operation, but I
> wanted to point out that this is not a harmless change.
>
>
> In the Array.prototype.slice.call(foo) use case what is foo? Is it known
> to be an Array?  Are you saying this is how you clone an Array?
>

Sorry, both are of that form, if I was unclear. When we want to simply
clone an existing array, belonging to a secured realm, I think we generally
use slice as a method, and there is no security property there.

Of the two cases I refer to, one is a function (the trademarking stamp())
which takes a list of objects as a parameter and needs to ensure that
successive stages of processing operate on exactly the same set of objects
and do not trigger any side effects in the list's implementation. Here,
realm is irrelevant but the list's implementation must be relied on, so in
practice we want an Array from stamp()'s own realm.

The other case is one where it is a cross-frame protocol and we
specifically want an object which belongs to 'our own' realm because its
prototypes are frozen and specially extended, whereas the calling realm's
prototypes notably are not frozen (it's outside of the shiny happy sandbox)
and therefore constitute a risk to least-authority programming which we
want to stop at the boundaries. (Note for MarkM: It's actually a little bit
more complicated than this, but the details are irrelevant to the
principle.)


> For you second use case, that sounds like it is contrary to what is
> implicitly assume by ES5.  For ES5, every built-in is assume to be
> associated with a realm when it is created and any references to built-ins
> by a built-in are assume to use the same realm as the referencing built-in.
>  So something like:
>        var newArray = slice.call( [ ] );
>

Sorry, when I said "the caller" I meant *this particular* caller, the
function in our codebase which contains "Array.prototype.slice" in its
source text and therefore does call the slice belonging to its own realm. I
apologize for the particularly misleading phrasing.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20130829/7afe3648/attachment-0001.html>
domenic at domenicdenicola.com (2013-08-31T21:06:50.113Z)
On Thu, Aug 29, 2013 at 12:56 PM, Allen Wirfs-Brock <allen at wirfs-brock.com> wrote:

> In the `Array.prototype.slice.call(foo)` use case what is `foo`? Is it known
> to be an `Array`?  Are you saying this is how you clone an `Array`?

Sorry, both are of that form, if I was unclear. When we want to simply
clone an existing array, belonging to a secured realm, I think we generally
use slice as a method, and there is no security property there.

Of the two cases I refer to, one is a function (the trademarking `stamp()`)
which takes a list of objects as a parameter and needs to ensure that
successive stages of processing operate on exactly the same set of objects
and do not trigger any side effects in the list's implementation. Here,
realm is irrelevant but the list's implementation must be relied on, so in
practice we want an `Array` from `stamp()`'s own realm.

The other case is one where it is a cross-frame protocol and we
specifically want an object which belongs to 'our own' realm because its
prototypes are frozen and specially extended, whereas the calling realm's
prototypes notably are not frozen (it's outside of the shiny happy sandbox)
and therefore constitute a risk to least-authority programming which we
want to stop at the boundaries. (Note for MarkM: It's actually a little bit
more complicated than this, but the details are irrelevant to the
principle.)


> For you second use case, that sounds like it is contrary to what is
> implicitly assume by ES5.  For ES5, every built-in is assume to be
> associated with a realm when it is created and any references to built-ins
> by a built-in are assume to use the same realm as the referencing built-in.
>  So something like:
>
> ```js
> var newArray = slice.call( [ ] );
> ```

Sorry, when I said "the caller" I meant *this particular* caller, the
function in our codebase which contains `Array.prototype.slice` in its
source text and therefore does call the slice belonging to its own realm. I
apologize for the particularly misleading phrasing.