Last Comment Bug 322312 - CVE-2006-0299 * ("AnyName") entrainment and (given future chrome use of e4x) access control hazard
: CVE-2006-0299 * ("AnyName") entrainment and (given future chrome use of e4x) ...
Status: VERIFIED FIXED
[sg:low (preventive)] patch in bug 32...
: verified1.8.0.1, verified1.8.1
Product: Core
Classification: Components
Component: JavaScript Engine (show other bugs)
: Trunk
: All All
: P1 normal (vote)
: mozilla1.9alpha1
Assigned To: Brendan Eich [:brendan]
:
Mentors:
javascript:AnyName.prototype.__proto_...
Depends on: 322499
Blocks:
  Show dependency treegraph
 
Reported: 2006-01-04 00:09 PST by Brendan Eich [:brendan]
Modified: 2006-02-02 09:33 PST (History)
6 users (show)
bob: in‑testsuite+
See Also:
Crash Signature:
(edit)
QA Whiteboard:
Iteration: ---
Points: ---
Has Regression Range: ---
Has STR: ---


Attachments
proposed minimal fix (2.55 KB, patch)
2006-01-04 00:10 PST, Brendan Eich [:brendan]
no flags Details | Diff | Splinter Review

Description Brendan Eich [:brendan] 2006-01-04 00:09:22 PST
The E4X AnyName spec type is implemented in SpiderMonkey using a native object class, but its only instance is a per-runtime singleton managed via a weak ref in the JSRuntime.

Bugs in the implementation expose this instance to script directly and via AnyName(), new AnyName(), and AnyName.prototype, whose __proto__  leads to the first accessing context global's Object.prototype, leading via __parent__ to a window.  If chrome uses * in a script loaded and cached across a long term, content script might be able to do naughty things.

Apart from access control concerns, the first context to use * in an overlapping episode of * usage will have its global object entrained via the AnyName singleton's prototype object, that context global's Object.prototype.  This is a bloat bug.

/be
Comment 1 Brendan Eich [:brendan] 2006-01-04 00:10:12 PST
Created attachment 207475 [details] [diff] [review]
proposed minimal fix
Comment 2 Brendan Eich [:brendan] 2006-01-04 00:14:27 PST
Actually, scripts don't hold onto the anyname object via atoms, they always use JSOP_ANYNAME to get that singleton (per runtime) on each * use.  So the only hole here is if a chrome script stores * in a long-lived property.  The jsparse.c patch dereferences * so it will never be accessible as a magic identifier object, closing that hole.

The jsxml.c patch avoids init'ing the AnyName class and nulls the singleton's proto slot to avoid bloat.

/be

Comment 3 Mike Shaver (:shaver -- probably not reading bugmail closely) 2006-01-04 05:36:02 PST
Comment on attachment 207475 [details] [diff] [review]
proposed minimal fix

Will that break use of * for fallback definition with __define[GS]etter__, as I had been so sagely counselled to pursue? =)
Comment 4 Daniel Veditz [:dveditz] 2006-01-04 08:11:51 PST
If this is a bloat bug what is the security risk that prompted the confidential flag?
Comment 5 Mike Shaver (:shaver -- probably not reading bugmail closely) 2006-01-04 08:27:36 PST
The summary alludes to an access control hazard, and comment #0 says:

> If chrome uses * in a script loaded and cached across a long term,
> content script might be able to do naughty things.

This bug can allow cross-context access, from the current script to whatever script caused the current rt->anyNameObject to be allocated.  If the allocating script was privileged, that's an escalation attack.  If it was just from another page, we still face cross-site scripting peril.
Comment 6 Brendan Eich [:brendan] 2006-01-04 10:31:19 PST
(In reply to comment #5)
> The summary alludes to an access control hazard, and comment #0 says:
> 
> > If chrome uses * in a script loaded and cached across a long term,
> > content script might be able to do naughty things.

But as I said in comment 2, scripts do not reference anyname from their literal pools (script->atomMap).  The issue is more obscure.  Due to the bug fixed by the jsparse.c patch, an extension could early on do something like

  longLivedProp = *;

and create a covert channel to any web content that uses * or the AnyName constructor.  Worse, if such an extension did this foolishly or maliciously, such subsequently-loaded web content could then attack Object.prototype (which has no access controls in its class getter and setter), and its __parent__, which is a chrome window (also lacking access checks in its getter and setter, IIRC).

> This bug can allow cross-context access, from the current script to whatever
> script caused the current rt->anyNameObject to be allocated.  If the allocating
> script was privileged, that's an escalation attack.  If it was just from
> another page, we still face cross-site scripting peril.

Right, as many trust domains as share the (wrongly exposed, to be hidden) * object can affect that object.  However, note that content is subject to same-origin checking at window boundaries, so attacking AnyName.prototype.__proto__.__parent__ from origin B targeting origin A should be stopped (this should be tested to make sure I'm not talking cheap).

The real hazard is if chrome stashes a long-lived reference to anyname.  Also bad is the covert channel through Object.prototype.  This can be used to spoof stuff like Object.prototype.toString.  Lesser hazards exist due to the wrongful sharing, and the bloat.

/be
Comment 7 Brendan Eich [:brendan] 2006-01-04 10:38:50 PST
(In reply to comment #6)
> Due to the bug fixed by
> the jsparse.c patch, an extension could early on do something like
> 
>   longLivedProp = *;

Just to be clear, the same thing could be done using AnyName.prototype, or new AnyName, instead of *.  The jsparse.c patch is important to hide the (supposedly internal) AnyName type, whose singleton instance can be named by * currently.  The #if 0 stubbed js_InitAnyNameClass guts in jsxml.c is also necessary to hide the other ways of getting a reference to this singleton.

/be
Comment 8 Brendan Eich [:brendan] 2006-01-04 12:15:42 PST
(In reply to comment #3)
> (From update of attachment 207475 [details] [diff] [review] [edit])
> Will that break use of * for fallback definition with __define[GS]etter__, as I
> had been so sagely counselled to pursue? =)

No, why would it?  * is an identifier, not a value (with this bug's fix-patch), it represents an internal type (which happens to be an object subtype in SpiderMonkey but need not be in other implementations).

/be
Comment 9 Mike Shaver (:shaver -- probably not reading bugmail closely) 2006-01-04 19:08:17 PST
Comment on attachment 207475 [details] [diff] [review]
proposed minimal fix

sr=shaver  Thanks for the schooling.
Comment 10 Blake Kaplan (:mrbkap) 2006-01-05 13:25:22 PST
Comment on attachment 207475 [details] [diff] [review]
proposed minimal fix

Does the jsparse.c part of this patch mean that the TOK_ANYNAME case in js_EmitTree won't ever be reached? r=mrbkap
Comment 11 Brendan Eich [:brendan] 2006-01-05 13:42:37 PST
Comment on attachment 207475 [details] [diff] [review]
proposed minimal fix

This patch isn't right, and isn't enough (look at the return value of js_InitAnyNameClass -- oops!).  Also, I've got a public bug to fix this in, and I'd rather use that, since the security hazards are so far not real, just potential.

Thoughts on closing this bug?

/be
Comment 12 Brendan Eich [:brendan] 2006-01-05 13:43:15 PST
(In reply to comment #11)
> Also, I've got a public bug to fix this in,

Bug 322499.

/be
Comment 13 Brendan Eich [:brendan] 2006-01-05 16:28:24 PST
Bug 322499 has a patch now, and I've marked that bug blocking1.8.1+ and blocking1.8.0.1+.  My hope was that this bug could be closed, but it has useful information for drivers.  I'll leave it to word-of-mouth to link the two bugs, unless someone has a better idea.

/be
Comment 14 Daniel Veditz [:dveditz] 2006-01-06 18:46:29 PST
confirmed that any page can add properties to the singleton AnyName to share information with any other page regardless of domain. Can't share self or document cross-domain, access checks prevent that, and I don't seem to get anywhere trying __proto__ or __parent__.

AnyName.prototype.valueOf.call() gets me [object JSDGlobal] but I don't know if I can do anything interesting there.

XSS is normally sg:high, but in this case it looks like you can only get to volunteered properties so guessing at sg:moderate (low?). Could lead to worse if chrome started using this feature.
Comment 15 Daniel Veditz [:dveditz] 2006-01-07 10:53:12 PST
> Could lead to worse if chrome started using this feature.

Brendan says there are, in fact, extensions using this feature :-(

Comment 16 Brendan Eich [:brendan] 2006-01-08 20:59:44 PST
(In reply to comment #15)
> > Could lead to worse if chrome started using this feature.
> 
> Brendan says there are, in fact, extensions using this feature :-(

What I said was that I know or have heard of extensions for 1.5 that use E4X.  I don't know whether any store a long-lived anyname reference.  Why take the chance?

/be
Comment 17 Bob Clary [:bc:] 2006-01-09 11:53:17 PST
AnyName is not defined in today's trunk builds on WinXP.
Comment 18 Brendan Eich [:brendan] 2006-01-09 12:27:52 PST
(In reply to comment #17)
> AnyName is not defined in today's trunk builds on WinXP.

Yes, this bug (and its oepn twin) is fixed on trunk.  See bug 322499 comment 3.  I guess this should be closed too.  I'm still inclined to unrestrict it and dup it. Dan, what do you think?

/be
Comment 19 Daniel Veditz [:dveditz] 2006-01-09 13:54:54 PST
I'd rather mark this dependent than a dupe because the information in it is different, but OK on clearing the confidential flag (comment 11)
Comment 20 Bob Clary [:bc:] 2006-01-12 10:19:31 PST
test in bug 322499
Comment 21 Bob Clary [:bc:] 2006-01-14 11:42:24 PST
v 20060113 windows/linux/mac 1.8.0.1, 1.8, 1.9a1 with the test in 322499.

Note You need to log in before you can comment on or make changes to this bug.