security check of js_ValueToFunctionObject() can be circumvented

VERIFIED FIXED in mozilla1.9alpha1

Status

()

Core
JavaScript Engine
P1
critical
VERIFIED FIXED
12 years ago
11 years ago

People

(Reporter: shutdown, Assigned: mrbkap)

Tracking

({verified1.8.0.2, verified1.8.1})

Trunk
mozilla1.9alpha1
verified1.8.0.2, verified1.8.1
Points:
---
Bug Flags:
blocking1.8.1 +
blocking1.8.0.2 +
in-testsuite +

Firefox Tracking Flags

(Not tracked)

Details

(Whiteboard: [sg:critical][rft-dl] doesn't affect ff1.0.x)

Attachments

(2 attachments, 1 obsolete attachment)

(Reporter)

Description

12 years ago
http://lxr.mozilla.org/seamonkey/source/js/src/jsfun.c#2123
2139     caller = JS_GetScriptedCaller(cx, cx->fp);
2140     if (caller &&
2141         !js_CheckPrincipalsAccess(cx, funobj,
2142                                   caller->script->principals,
2143                                   JS_GetFunctionName(fun))) {

This security check can be circumvented by using setTimeout()
or similar that calls a function without any scripted caller.
(Reporter)

Comment 1

12 years ago
Created attachment 208544 [details]
testcase

privilege escalation testcase

Works on:
Mozilla/5.0 (Windows; U; Win98; en-US; rv:1.9a1) Gecko/20060114 Firefox/1.6a1
Mozilla/5.0 (Windows; U; Win98; en-US; rv:1.8) Gecko/20060114 Firefox/1.5

Updated

12 years ago
Flags: blocking1.8.0.2?
Whiteboard: [sg:critical]
Created attachment 208546 [details] [diff] [review]
proposed fix

Clever testcase.  I blame the Array extras added for JS1.6 (half-kidding, shaver ;-).  Compare the Function case (visible in patch due to fix to use the declared string constant), where if there's no scripted caller, principals is null and the check will fail.

In the js_ValueTo{Function,Callable}Object case, we don't give up so easily.  If the callee's object principals (the callee is Array.forEach) subsume those of the callable, we're ok.  So chrome could use setTimeout as this testcase does, and it would work as it should.

I wish eval weren't a universal method, but we can't fix that this time around.

/be
Attachment #208546 - Flags: superreview?(shaver)
Attachment #208546 - Flags: review?(mrbkap)

Comment 3

12 years ago
tests/mozilla.org/security/323501-01.html
Flags: testcase+

Updated

12 years ago
Assignee: general → brendan

Updated

12 years ago
Status: NEW → ASSIGNED
Flags: blocking1.8.1?
Priority: -- → P1
Target Milestone: --- → mozilla1.9alpha
(Assignee)

Comment 4

12 years ago
Comment on attachment 208546 [details] [diff] [review]
proposed fix

The extra effort to get the principals from the callee scare me here. This means that if you manage to get your hands on a priviledged Array object, you'd be able to do this same exploit. I know that AJAX people are using this stuff, but setTimeout(Array.forEach, ...) feels like a real edge case. If this starts biting people, I'd argue for adding a belt (or is it braces?) to the array extras.
Attachment #208546 - Flags: review?(mrbkap) → review-
(Assignee)

Comment 5

12 years ago
(In reply to comment #4)
> If this starts biting people, I'd argue for adding a belt (or is it braces?) to the array
> extras.

Of course, I mean in addition to getting the principals from the callee.
Comment on attachment 208546 [details] [diff] [review]
proposed fix

clearing req based on mrbkap's r-.
Attachment #208546 - Flags: superreview?(shaver)
(Assignee)

Comment 7

12 years ago
Created attachment 209540 [details] [diff] [review]
safer fix

This is basically brendan's fix, but without the scary get-principals-from-callee behavior.
Assignee: brendan → mrbkap
Attachment #208546 - Attachment is obsolete: true
Attachment #209540 - Flags: superreview?(shaver)
Attachment #209540 - Flags: review?(brendan)
Comment on attachment 209540 [details] [diff] [review]
safer fix

> js_ValueToFunctionObject(JSContext *cx, jsval *vp, uintN flags)
> {
>     JSFunction *fun;
>     JSObject *funobj;
>-    JSStackFrame *caller;
>+    JSStackFrame *fp, *caller;
>+    JSPrincipals *principals;
> 
>     if (JSVAL_IS_FUNCTION(cx, *vp))
>         return JSVAL_TO_OBJECT(*vp);
> 
>     fun = js_ValueToFunction(cx, vp, flags);
>     if (!fun)
>         return NULL;
>     funobj = fun->object;
>     *vp = OBJECT_TO_JSVAL(funobj);
> 
>-    caller = JS_GetScriptedCaller(cx, cx->fp);
>-    if (caller &&
>-        !js_CheckPrincipalsAccess(cx, funobj,
>-                                  caller->script->principals,
>-                                  JS_GetFunctionName(fun))) {
>+    fp = cx->fp;
>+    caller = JS_GetScriptedCaller(cx, fp);

Minimize the patch by eliminating fp again -- it's a single-use variable.  Fix that and r=me.

/be

>+    if (caller) {
>+        principals = caller->script->principals;
>+    } else {
>+        /* No scripted caller, don't allow access. */
>+        principals = NULL;
>+    }
>+
>+    /*
>+     * FIXME: Reparameterize so we don't call js_AtomToPrintableString unless
>+     *        there is an error.
>+     */
>+    if (!js_CheckPrincipalsAccess(cx, funobj, principals,
>+                                  fun->atom
>+                                  ? js_AtomToPrintableString(cx, fun->atom)
>+                                  : js_anonymous_str)) {
>         return NULL;
>     }
>     return funobj;
> }
> 
> JSObject *
> js_ValueToCallableObject(JSContext *cx, jsval *vp, uintN flags)
> {
>     JSObject *callable;
>
Attachment #209540 - Flags: review?(brendan) → review+
(Assignee)

Comment 9

12 years ago
Fix checked into trunk.
Status: ASSIGNED → RESOLVED
Last Resolved: 12 years ago
Resolution: --- → FIXED
Flags: blocking1.8.1?
Flags: blocking1.8.1+
Flags: blocking1.8.0.2?
Flags: blocking1.8.0.2+
(Assignee)

Comment 10

12 years ago
Comment on attachment 209540 [details] [diff] [review]
safer fix

I think we want this on the 1.8 branches, but I need approval.
Attachment #209540 - Flags: approval1.8.0.2?
Comment on attachment 209540 [details] [diff] [review]
safer fix

approved for 1.8.0 branch, a=dveditz for drivers
Attachment #209540 - Flags: approval1.8.0.2? → approval1.8.0.2+
(Assignee)

Comment 12

12 years ago
Fix checked into the 1.8 branches.
Keywords: fixed1.8.0.2, fixed1.8.1

Updated

12 years ago
Whiteboard: [sg:critical] → [sg:critical][rft-dl]
Whiteboard: [sg:critical][rft-dl] → [sg:critical][rft-dl] doesn't affect ff1.0.x

Comment 13

12 years ago
v.fixed on 1.8.0 branch with Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.1) Gecko/20060301 Firefox/1.5.0.1, anonymous function call blocked in testcase.
Keywords: fixed1.8.0.2 → verified1.8.0.2

Comment 14

11 years ago
testcase does not alert in Bon Echo 20060517 / winxp or Minefield 20060517 / winxp  and does show the error message.
Status: RESOLVED → VERIFIED
Keywords: fixed1.8.1 → verified1.8.1
Group: security

Updated

11 years ago
Keywords: fixed1.8.1

Updated

11 years ago
Keywords: fixed1.8.1

Comment 15

11 years ago
shutdown,  can you contact me at chofmann@mozilla.org?  Having a problem getting mail though to you.  thanks.
Attachment #209540 - Flags: superreview?(shaver)
You need to log in before you can comment on or make changes to this bug.