Closed Bug 767686 Opened 12 years ago Closed 12 years ago

Chrome can't retrieve a chrome-only property if the object is wrapped in a SafeJSObjectWrapper

Categories

(Core :: XPConnect, defect)

defect
Not set
normal

Tracking

()

RESOLVED INVALID

People

(Reporter: neil, Unassigned)

References

Details

You may consider this bug to be invalid, but it makes DOM Inspector harder to use :-(

If you have a content object, and attempt to retrieve a chrome-only property on it, and the object has been unwrapped from its XrayWrapper, then the attempt to retrieve the chrome-only property executes with the principal of the content object and therefore gets vetoed by the security manager.

For example, if you inspect a content document in DOM Inspector, select a <textarea> element, switch to JavaScript Object view and attempt to evaluate target.QueryInterface(Components.interfaces.nsIDOMNSEditableElement).editor then an exception is thrown: "The operation is insecure."

However in Gecko 2 this works as expected and returns the nsIEditor object.

The workaround is to evaluate XPCNativeWrapper(target).QueryInterface(Components.interfaces.nsIDOMNSEditableElement).editor i.e. restore the XrayWrapper that DOM Inspector removes.
Well, yes. If you waive Xray vision, you get whatever JS behavior the content code may have defined, which has to be unprivileged to avoid privilege escalation.

For example, if content defined 'target.QueryInterface = function() {alert('hah');}', the contract of target.wrappedJSObject.QueryInterface(..)) is to show the alert. And in case if the function did something nastier than just alert, we definitely don't want to be running that code with content privileges.

By default, Xray wrapper gives you the expected behavior. If you unwrap / waive Xray, you're explicitly giving that up in favor of being able to run whatever content JS might be attached to the object. I don't see how we could mix these behaviors in a sane way.
Feel free to reopen if you have a proposal of how this might work.
Status: NEW → RESOLVED
Closed: 12 years ago
Resolution: --- → INVALID
(In reply to Bobby Holley (:bholley) from comment #1)
> And in case if the function did something nastier than
> just alert, we definitely don't want to be running that code with content
> privileges.

Er, with *chrome* privileges.
Sure, but how come this works in Gecko 2?
(In reply to neil@parkwaycc.co.uk from comment #4)
> Sure, but how come this works in Gecko 2?

Presumably because there was a bug. If you're interested in the exact reason, bisecting to the first failing changeset would be the first step.
(In reply to Bobby Holley from comment #5)
> (In reply to neil@parkwaycc.co.uk from comment #4)
> > Sure, but how come this works in Gecko 2?
> Presumably because there was a bug.
Not sure why you would think chrome being able to retrieve a chrome property through either an XPCNativeWrapper or SafeJSObjectWrapper was a bug.

By comparison, if I embed a function in the content window that attempts to retrieve aforementioned chrome property, and call that function from chrome, then it throws a security error.

> bisecting to the first failing changeset would be the first step.
OK, I'll see what I can do.
(In reply to neil@parkwaycc.co.uk from comment #6)
> OK, I'll see what I can do.
Not very much, it appears - I have GCC 7 so I can only go back to March 15...
(In reply to neil@parkwaycc.co.uk from comment #6)
> > Presumably because there was a bug.
> Not sure why you would think chrome being able to retrieve a chrome property
> through either an XPCNativeWrapper or SafeJSObjectWrapper was a bug.

We're talking about the later case here, and IMO it would be a bug.

If content defines target.QueryInterface = 42, then the SJOW should see 42. That's the contract - SJOWS give chrome transparent delegation, i.e. they see things exactly the way content sees them. As soon as we run content JS, we have no way of knowing whether the intended function was called. Even if we end up back in C++, content might have defined target.getElementById = target.QueryInterface or something like that.

From both a sanity and a practical architectural standpoint, the only thing we can do here is to enter the content compartment. And once we do, we're effectively unprivileged. 
 
> By comparison, if I embed a function in the content window that attempts to
> retrieve aforementioned chrome property, and call that function from chrome,
> then it throws a security error.

A chrome function or a content function? The former should work, and the latter should throw.

(In reply to neil@parkwaycc.co.uk from comment #7)
> (In reply to neil@parkwaycc.co.uk from comment #6)
> > OK, I'll see what I can do.
> Not very much, it appears - I have GCC 7 so I can only go back to March 15...

I wouldn't worry about it too much unless we can conclude that the current behavior is wrong.
(In reply to Bobby Holley from comment #8)
> From both a sanity and a practical architectural standpoint, the only thing
> we can do here is to enter the content compartment.
Ah, so this would have regressed when compartments landed. Presumably the security was previously enforced in a different way which allowed chrome to access chrome-only objects through an SJOW.

> > By comparison, if I embed a function in the content window that attempts to
> > retrieve aforementioned chrome property, and call that function from chrome,
> > then it throws a security error.
> A chrome function or a content function? The former should work, and the
> latter should throw.
I didn't try a chrome function, but the latter does indeed throw both in Gecko 2 and on trunk.
(In reply to neil@parkwaycc.co.uk from comment #9)

> Ah, so this would have regressed when compartments landed. Presumably the
> security was previously enforced in a different way which allowed chrome to
> access chrome-only objects through an SJOW.

That was my initial thought, but you said it worked in Gecko 2 (FF4), which included the compartments landing. I wasn't working on XPConnect then, so I don't know the history of what landed in FF4 and what was pushed to FF5.
This really confused me when I wanted to look at the plugin problem binding in DOM Inspector's JavaScript Object view. It wants to unwrap everything, but this doesn't work very well as the binding is inaccessible to content.
This will be fixed with bug 825392.
Depends on: 825392
You need to log in before you can comment on or make changes to this bug.