Closed Bug 522430 (CVE-2009-3986) Opened 15 years ago Closed 15 years ago

window.opener allows chrome access from unprivileged pages

Categories

(Core :: DOM: Core & HTML, defect, P2)

defect

Tracking

()

RESOLVED FIXED
mozilla1.9.2
Tracking Status
status1.9.2 --- beta2-fixed
blocking1.9.1 --- .6+
status1.9.1 --- .6-fixed

People

(Reporter: james82, Assigned: mrbkap)

References

Details

(Keywords: verified1.9.0.16, verified1.9.1, Whiteboard: [sg:moderate])

Attachments

(1 file, 1 obsolete file)

User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.4) Gecko/20091007 Firefox/3.5.4 Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.4) Gecko/20091007 Firefox/3.5.4 When new windows are opened in Firefox, the new window has a reference to the window that created it using window.opener. If window.opener is a ChromeWindow, then any webpage opened in this window will be able to access the functions inside the ChromeWindow. Both Firefox itself and many extensions for Firefox often open windows from within chrome code. With this security hole, windows opened by chrome code are unsafe. Reproducible: Always Steps to Reproduce: 1. Select Help -> About Mozilla Firefox 2. Click on "Licensing Information" 3. A new window will open with licensing information. In this window, go to http://www.google.com 4. In the URL bar, type javascript:window.opener.URLBarSetURI({spec:"https://www.ebay.com/"},true) 5. In the URL bar, type javascript:window.opener.BrowserOffline.toggleOfflineStatus() 6. Browse to a web page that contains the above code in a script tag. Note that Firefox's security model does not prevent this code from running. Actual Results: 1. The URL bar of the opening window is set to "https://www.ebay.com/" 2. The browser is set to work offline 3. Web pages can access and run chrome code Expected Results: The new window should not be able to access properties of the chrome window. This bug likely effects not just Firefox itself, but also many extensions which open windows using window.open.
Blake: Weren't XOW supposed to protect us from this? (Note: The JS in step 4 doesn't actually work for me, but step 5 definitely does.)
Assignee: nobody → mrbkap
Status: UNCONFIRMED → NEW
blocking1.9.1: --- → .5+
Ever confirmed: true
Flags: wanted1.9.0.x+
Flags: blocking1.9.0.16+
Flags: blocking-firefox3.6?
OS: Windows XP → All
Hardware: x86 → All
Whiteboard: [sg:moderate]
Version: unspecified → Trunk
Once you've done this it's trivial to exploit to gain sg:crit access. Is this sg:moderate only because you have to do something "unusual" to get the browser to do this bad window.open? (To exploit, call openURI with a chrome URI and then a javascript URI). I thought we nulled out window.opener when a chrome-privileged page calls window.open without the "chrome" feature, but I can't find the code to actually do that.
It's "moderate" because we don't know of any Firefox dialogs that will open random pages in this way. There is quite a bit of mitigation value if an attacker has to tell the user 1) open the about dialog 2) click the license link 3) now please come visit my page in that window (type the URL, paste it, use a bookmark) It's more likely that some add-on somewhere is doing something like this although we don't know of any specific examples. It would be an sg:critical bug for users of that add-on. Does that make it sg:critical overall? Always? Only if the addon is really popular? I don't know, maybe. I guess that's a long-winded "yes" to your question.
It's not 'any' window opened by 'any' chrome dialog. New windows opened from the bookmarks/history dialog don't do this, for instance. Is it limited to XUL <label class="text-link"> links?
This bug doesn't affect 'any' windows opened from chrome, but it does impact common ways of opening windows from chrome. Here are some more examples: Reproduction Recipe A: 1) Install LiveHTTPHeaders 2) Go to Tools -> LiveHttpHeaders 3) Select About -> Check for update 4) In the new window, type the URL: "javascript:window.opener" This shows that LiveHTTPHeaders opens a hole with this code: document.commandDispatcher.focusedWindow.open(url); Reproduction Recipe B: 1) Go to Tools -> Options -> Tabs and deselect "Open new windows in a new tab instead" 2) Install YSlow 3) Run YSlow on your favourite website 4) Open the YSlow Panel and click an external link 5) In the new window, type the URL: "javascript:window.opener" This shows that YSlow opens a hole with the following code: window.open(url, " blank");
(In reply to comment #1) > Blake: Weren't XOW supposed to protect us from this? (Note: The JS in step 4 > doesn't actually work for me, but step 5 definitely does.) Sort of -- the problem is that the object we're handing out is *so* wrong, XOWs don't even notice.
Component: Security → DOM
Flags: blocking-firefox3.6?
Product: Firefox → Core
QA Contact: firefox → general
Target Milestone: --- → mozilla1.9.2
Flags: blocking1.9.2?
Attached patch Proposed fixSplinter Review
Easy fix: don't return an opener if we're not chrome and the window that we're returning is a chrome window (even content windows with chrome privileges get wrapped and protected).
Attachment #407407 - Flags: superreview?(jonas)
Attachment #407407 - Flags: review?(jst)
Attached patch Assertion (obsolete) — Splinter Review
I don't want to land this at the same time as attachment 407407 [details] [diff] [review] because I think this assertion + that fix make the problem here extremely obvious to interested onlookers. This assertion checks to make sure that we don't ever try to wrap a chrome window in a content scope. As a belt and braces, we could either throw in these cases, or wrap all [object ChromeWindow]s in SystemOnlyWrappers.
Attachment #407408 - Flags: review?(jst)
Attachment #407407 - Flags: review?(jst) → review+
Flags: blocking1.9.2? → blocking1.9.2+
Priority: -- → P2
Attachment #407407 - Flags: superreview?(jonas) → superreview+
Blake, can you land this for trunk and 1.9.2?
Status: NEW → RESOLVED
Closed: 15 years ago
Resolution: --- → FIXED
Attachment #407407 - Flags: approval1.9.1.6?
Comment on attachment 407407 [details] [diff] [review] Proposed fix Does the lack of a 1.9.0.16 approval request mean we need a different back-port? Or just an oversight?
Comment on attachment 407407 [details] [diff] [review] Proposed fix In this case it means that I forgot to request approval.
Attachment #407407 - Flags: approval1.9.0.16?
Comment on attachment 407407 [details] [diff] [review] Proposed fix Approved for 1.9.1.6 and 1.9.0.16, a=dveditz for release-drivers
Attachment #407407 - Flags: approval1.9.1.6?
Attachment #407407 - Flags: approval1.9.1.6+
Attachment #407407 - Flags: approval1.9.0.16?
Attachment #407407 - Flags: approval1.9.0.16+
Keywords: checkin-needed
Fixed in CVS.
Keywords: fixed1.9.0.16
Verified fixed in 1.9.1.6 with Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.6pre) Gecko/20091119 Shiretoko/3.5.6pre (.NET CLR 3.5.30729) using steps in comment 0. Used steps in comment 5 for 1.9.0.16 since the licensing link doesn't exist in 1.9.0. Verified fixed for 1.9.0.16 with Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.16pre) Gecko/2009111921 GranParadiso/3.0.16pre (.NET CLR 3.5.30729).
Alias: CVE-2009-3986
Attachment #407408 - Flags: review?(jst) → review+
Group: core-security
I had to back that out because we hit it on tinderbox alive tests... http://hg.mozilla.org/mozilla-central/rev/61cd29e06840
Status: RESOLVED → REOPENED
Resolution: FIXED → ---
Status: REOPENED → RESOLVED
Closed: 15 years ago15 years ago
Resolution: --- → FIXED
Blocks: 554410
Comment on attachment 407408 [details] [diff] [review] Assertion Sadly, we can't do this. Given code like: var chromeWin = aWindow .QueryInterface(Ci.nsIInterfaceRequestor) .getInterface(Ci.nsIWebNavigation) .QueryInterface(Ci.nsIDocShellTreeItem) .rootTreeItem .QueryInterface(Ci.nsIInterfaceRequestor) .getInterface(Ci.nsIDOMWindow) .QueryInterface(Ci.nsIDOMChromeWindow); on a content window (through an XPCNativeWrapper, even), we start in a content scope (the window)... when GI to docshelltreeitem, we create a docshell JS object in the scope we think we're in (i.e. the content window), then when we get the DOMWindow from that, we wrap it in the current scope, which is still the content window... But it's not *really* in that scope, we just think it is.
Attachment #407408 - Attachment is obsolete: true
Component: DOM → DOM: Core & HTML
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: