Closed Bug 322312 Opened 19 years ago Closed 19 years ago

CVE-2006-0299 * ("AnyName") entrainment and (given future chrome use of e4x) access control hazard

Categories

(Core :: JavaScript Engine, defect, P1)

defect

Tracking

()

VERIFIED FIXED
mozilla1.9alpha1

People

(Reporter: brendan, Assigned: brendan)

References

()

Details

(Keywords: verified1.8.0.1, verified1.8.1, Whiteboard: [sg:low (preventive)] patch in bug 322499 (fixed on trunk))

Attachments

(1 obsolete file)

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
Attached patch proposed minimal fix (obsolete) — Splinter Review
Attachment #207475 - Flags: superreview?(shaver)
Attachment #207475 - Flags: review?(mrbkap)
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

Status: NEW → ASSIGNED
Priority: -- → P1
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? =)
If this is a bloat bug what is the security risk that prompted the confidential flag?
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.
(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
(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
(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 on attachment 207475 [details] [diff] [review]
proposed minimal fix

sr=shaver  Thanks for the schooling.
Attachment #207475 - Flags: superreview?(shaver) → superreview+
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
Attachment #207475 - Flags: review?(mrbkap) → review+
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
Attachment #207475 - Attachment is obsolete: true
Attachment #207475 - Flags: superreview+
Attachment #207475 - Flags: review+
(In reply to comment #11)
> Also, I've got a public bug to fix this in,

Bug 322499.

/be
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
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.
Whiteboard: [sg:moderate] patch in bug 322499
> Could lead to worse if chrome started using this feature.

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

Whiteboard: [sg:moderate] patch in bug 322499 → [sg:high+] patch in bug 322499
Keywords: qawanted
Flags: blocking1.8.1+
Flags: blocking1.8.0.1+
Whiteboard: [sg:high+] patch in bug 322499 → [sg:high+] patch in bug 322499 (fixed on trunk)
(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
AnyName is not defined in today's trunk builds on WinXP.
(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
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)
Group: security
Status: ASSIGNED → RESOLVED
Closed: 19 years ago
Depends on: 322499
Flags: blocking1.8.1+
Flags: blocking1.8.0.1+
Keywords: qawanted
Resolution: --- → FIXED
Whiteboard: [sg:high+] patch in bug 322499 (fixed on trunk) → [sg:low (preventive)] patch in bug 322499 (fixed on trunk)
test in bug 322499
Flags: testcase+
v 20060113 windows/linux/mac 1.8.0.1, 1.8, 1.9a1 with the test in 322499.
Status: RESOLVED → VERIFIED
Summary: * ("AnyName") entrainment and (given future chrome use of e4x) access control hazard → CVE-2006-0299 * ("AnyName") entrainment and (given future chrome use of e4x) access control hazard
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: