Closed Bug 360529 Opened 18 years ago Closed 16 years ago

Arbitrary code execution using XSS hole and feed preview page


(Firefox Graveyard :: RSS Discovery and Preview, defect, P2)

Windows XP


(Not tracked)

Firefox 3


(Reporter: moz_bug_r_a4, Assigned: asaf)



(Keywords: verified1.8.1.17, Whiteboard: [sg:critical])


(4 files, 2 obsolete files)

Please see bug 353266.

Array.prototype methods trick (bug 344495) and document.(open|write) trick (bug
346659) and XSS holes (bug 351370, bug 359137) are available on fx2.0. (bug
359137 was already fixed.)

In a feed preview page, an event handler that was registered by content script
can be called by chrome script via elem.doCommand() or elem.dispatchEvent(). 
In this case, the event handler's scripted caller is chrome script.  Thus, an
attacker can run arbitrary code with chrome privileges by using Array.prototype
methods trick or document.write trick.

   .addEventListener("command", x, true);

   .observe({}, "nsPref:changed", "browser.feeds.handler.default");

x() (if x is a function) or x.handleEvent() is called in
FeedWriter._setSelectedHandler() via handlers[0].doCommand(),
selectedAppMenuItem.doCommand() or liveBookmarksMenuItem.doCommand().

   .addEventListener("CheckboxStateChange", y, true);

   .observe({}, "nsPref:changed", "browser.feeds.handler");

y() or y.handleEvent() is called in FeedWriter._setCheckboxCheckedState() via

* Fx1.5.0.x is not affected since it does not have feed preview feature.
* The trunk should be exploitable if an XSS hole existed.
The old testcases no longer work, since those try to use the XSS hole (bug
351370) that has been already fixed.  I'm attaching new testcases that use
another XSS hole (Bug 363597).
Is there any chance this can be fixed without relying on fixing bug 344495?
Is this still a problem in current trunk/branch build?
Flags: blocking-firefox3?
Yes, at least on 1.8 branch.  It's still possible to use the feed preview page
to turn an XSS bug into an arbitrary code execution bug.
Depends on: 393762
Flags: blocking1.8.1.13?
Flags: blocking1.8.1.12?
Flags: blocking-firefox3?
Whiteboard: [sg:critical]
Flags: blocking1.8.1.13?
Flags: blocking1.8.1.13+
Flags: blocking1.8.1.12?
Repeating the question:
(In reply to comment #7)
> Is this still a problem in current trunk/branch build?

If this is branch only, could the bug be marked as gecko-1.8branch/ff-2.0branch?

Flags: blocking-firefox3?
Whether or not it's a trunk problem depends on whether there are any known universal-xss vulnerabilities on the trunk, or will be any found (or made) in the future. We've gone to a lot of trouble to make sure content can't open any chrome-privileged URIs precisely because we didn't trust that there were no such holes, but being able to open frames on arbitrary feeds means that web content _can_ still open chrome-privileged frames.

The only true solution is to make the Feed preview non-privileged. The privileged part could be a separate chrome-privileged sheet-like thing much like an oversized infobar.
Flags: wanted1.8.1.x+
Not gonna block Firefox 3 on this for now, but if you find that potential XSS vuln or figure out a fix for branch, please renom.
Flags: blocking-firefox3? → blocking-firefox3-
sayrer, is this something you can look at?
(In reply to comment #14)
> sayrer, is this something you can look at?

Mano dealt with this stuff last time, and came up with the Fx2 solution. I am really busy with other stuff--a summary of the attributes and elements used for the attack would be much appreciated.
Assignee: nobody → jst
Mano, do you have time to look at this in the next week? We're about a week away from our branch freeze.
Assignee: jst → mano
(In reply to comment #13)
> Not gonna block Firefox 3 on this for now, but if you find that potential XSS
> vuln or figure out a fix for branch, please renom.

We find XSS fairly regularly, it needs to get fixed.

Flags: blocking-firefox3- → blocking-firefox3?
Attached patch patchSplinter Review
Attachment #306777 - Flags: superreview?(jst)
Attachment #306777 - Flags: review?(sayrer)
Target Milestone: --- → Firefox 3
Attachment #306777 - Flags: review?(sayrer) → review+
Whiteboard: [sg:critical] → [sg:critical][need sr jst]
Attachment #306777 - Flags: superreview?(jst) → superreview+
Attachment #306777 - Flags: approval1.9b4?
Whiteboard: [sg:critical][need sr jst] → [sg:critical]
Comment on attachment 306777 [details] [diff] [review]

Attachment #306777 - Flags: approval1.9b4? → approval1.9b4+
mozilla/browser/components/feeds/src/FeedWriter.js 1.53
Closed: 16 years ago
Priority: -- → P1
Resolution: --- → FIXED
Mano, does this same patch apply to the branch? If so, can you request approval? If not, a branch-specific one would be great.
Attached patch untested branch patch (obsolete) — Splinter Review
I don't have a tree to this one on.
Flags: blocking-firefox3? → blocking-firefox3+
It seems that appendChild(), removeAttribute(), etc. are also exploitable,
since those methods fire mutation events.
Resolution: FIXED → ---
Followup bug would be better unless the landed patch is backed out.

Let's keep using this one.
Attachment #307041 - Flags: review?(dveditz)
Whiteboard: [sg:critical] → [sg:critical][needs new patch]
This needs a complete trunk patch before we can take it on the branch. Punting to the next release.
Flags: blocking1.8.1.14+
Flags: blocking1.8.1.13-
Flags: blocking1.8.1.13+
Target Milestone: Firefox 3 → Firefox 3 beta5
Mike and I agreed to push this to early-post-beta given the scale of my upcoming rewrite.
Target Milestone: Firefox 3 beta5 → Firefox 3
Priority: P1 → P2
So, after thinking about this a little more, I'm going to just rely on the fact that DOMAttrModified and other mutation events are not being dispatched for nodes which are not yet inserted into the document (and call appendChild within the sandbox).
In the js console:
var a=function() { alert('foo'); }; document.addEventListener("DOMAttrModified", a, true); var b = document.createElement("b"); b.setAttribute("f", "b"); document.documentElement.appendChild(b); b.setAttribute("m", "f");

alerts only for the second setAttribute call. Boris, Jonas,  Johnny: Can the feedwriter code rely on this? W3C's documentation is pretty vague about mutation events behavior for nodes which are not yet inserted into the document.
Mutation events do get dispatched, but in your testcase the event can't 
propagate to document, because element isn't in document.
But if you add mutation event listener to the element, the listener will be
I'm fine with that, we create the elements and set the attributes on the same time. Would it be enough than to call appendChild and all  _post_ node-insertion, attribute-modifications methods  in the sandbox?
Attached patch wip (obsolete) — Splinter Review
Attached patch patchSplinter Review
Attachment #311020 - Attachment is obsolete: true
Attachment #311175 - Flags: review?(mconnor)
Comment on attachment 311175 [details] [diff] [review]

>-      feedTitleLink.setAttribute("title", titleText);
>+      this._contentSandbox.feedTitleLink = feedTitleLink;
>+      this._contentSandbox.titleText = titleText;
>+      var codeStr = "feedTitleLink.setAttribute('title', titleText);";
>+      Cu.evalInSandbox(codeStr, this._contentSandbox);
>       this._safeSetURIAttribute(feedTitleLink, "href", 
>                                 parts.getPropertyAsAString("link"));

can null these after to clean up

>   _setSubscribeUsingLabel: function FW__setSubscribeUsingLabel() {
>-    var stringLabel = null;
>-    switch (this._getFeedType()) {
>+    var stringLabel;
>+    var feedType = this._getFeedType();
>+    switch (feedType) {

you don't use feedType elsewhere, don't understand the change here.

>       case Ci.nsIFeed.TYPE_VIDEO:
>         stringLabel = "subscribeVideoPodcastUsing";
>         break;
>       case Ci.nsIFeed.TYPE_AUDIO:
>         stringLabel = "subscribeAudioPodcastUsing";
>         break;
>       default:
>         stringLabel = "subscribeFeedUsing";
>     }

you could just init stringLabel to this and it'd be a little less code overall, but that's being nitpicky.

r=me, this should be pretty safe, just needs to get tested thoroughly by QA tomorrow...
Attachment #311175 - Flags: review?(mconnor) → review+
Attachment #311175 - Flags: approval1.9b5?
Comment on attachment 311175 [details] [diff] [review]

a1.9b5 on this patch, as its fixing an sg:critical bug and has potential regression impact in the wild.

Please make sure that the existing litmus tests cover the functionality we're touching here, and send mail to asking that they be run ASAP on all platforms.  If there are missing tests, please tell QA what the tests should cover.
Attachment #311175 - Flags: approval1.9b5? → approval1.9b5+
It seems to me that this wouldn't be too hard to automate testing on? (not that I'm volunteering - my plate is plenty full)

The testcases seem to basically be already written (some modification so they don't use an alert box maybe, but that shouldn't be too hard either...)
Flags: in-testsuite?
No, you cannot test this, we generally fix XSS holes :p
right but, if we can exploit said vulnerability in a test, the test should fail, right?
But we cannot. As far as i can tell, none of the tests attached here can be used to test this bug on current trunk.
XSS-like conditions can be created by code with UniversalXPConnect privileges, no?
I couldn't find a way (even with privileges enabled) to call about:feed's SubscribeHandler.init on trunk without using the console / urlbar as described in testcase 6. 
Attached patch for checkinSplinter Review
I'll write some tests later as we figure out how to do so...
mozilla/browser/components/feeds/src/FeedWriter.js 1.54

Mail sent to qa@m.c.
Closed: 16 years ago16 years ago
Resolution: --- → FIXED
> without using the console / urlbar as described in testcase 6. 

So if you inject code into the Firefox window that calls eval(content.code), it doesn't work?
Firefox window as in browser.xul? I guess that might work, though it requires the chrome-testing framework....
Why?  You can do that from inside a mochitest if you really want to...

Doing it from chrome mochitests might work as long as you can get the feed preview page loaded first.
Blocks: 425010
No longer blocks: 425010
Depends on: 425010
Is there any work being done here for an updated branch patch, presumably one that also includes a fix for bug 430658?
Whiteboard: [sg:critical][needs new patch] → [sg:critical][needs new branch patch]
Still don't have a branch patch and given the size of the trunk patch we don't want to take it at the last minute. Moving to, but we need to get a patch soon so we can land it early in the cycle.
Flags: blocking1.8.1.16+
Flags: blocking1.8.1.15-
Flags: blocking1.8.1.15+
Mano, we could really use a branch patch here...
Attachment #307041 - Attachment is obsolete: true
Attachment #334770 - Flags: review?(mconnor)
Attachment #307041 - Flags: review?(dveditz)
Comment on attachment 334770 [details] [diff] [review]
combined branch patch

This feels like pain.
Attachment #334770 - Flags: review?(mconnor) → review+
Attachment #334770 - Flags: approval1.8.1.17?
qanote: testcase 7 can't be used to verify because the stepping-stone bug was fixed in FF2.0.0.15. Either we need a testcase that uses another yet-unfixed XSS bug, or this patch needs to be verified by applying the patch to a source tree.
Comment on attachment 334770 [details] [diff] [review]
combined branch patch

It'd be good to get a second review given the size of the patch and the limited testing time we've got left for this release. Johnny: you reviewed an earlier iteration, you up for it?
Attachment #334770 - Flags: review?(jst)
Whiteboard: [sg:critical][needs new branch patch] → [sg:critical]
Attachment #334770 - Flags: review?(jst) → review+
Comment on attachment 334770 [details] [diff] [review]
combined branch patch

Approved for Please land ASAP on the branch. a=ss
Attachment #334770 - Flags: approval1.8.1.17? → approval1.8.1.17+
Checking in src/FeedWriter.js;
/cvsroot/mozilla/browser/components/feeds/src/FeedWriter.js,v  <--  FeedWriter.js
new revision:; previous revision:
Keywords: fixed1.8.1.17
The fx2 patch caused a syntax error on Windows.

Here is an extra "}".

Error: missing catch or finally after try
Source File: file:///C:/test/fx-
Line: 736, Column: 6
Source Code:
      else {

Error: BrowserFeedWriter is not defined
Source File: chrome://browser/content/feeds/subscribe.js
Line: 45
Preeeetty sure we need the syntax error fixed before we can ship, so unmarking it as branch-fixed until that's addressed.

How did this code ever work in testing the #ifdef XP_WIN block?  We really, *really* can't be checking untested code into the stable branches, so I'm very much hoping that something else happened. :(
Keywords: fixed1.8.1.17
Bad merge :-/
With that fixed I get:
Error: uncaught exception: [Exception... "'[JavaScript Error: "result has no properties" {file: "file:///I:/mozb/mozilla/ff-opt/dist/bin/components/FeedWriter.js" line: 381}]' when calling method: [nsIFeedWriter::write]"  nsresult: "0x80570021 (NS_ERROR_XPC_JAVASCRIPT_ERROR_WITH_DETAILS)"  location: "JS frame :: chrome://browser/content/feeds/subscribe.js :: SH_init :: line 46"  data: yes]

with all of the testcases, along with:
Security Error: Content at about:feeds may not load or link to chrome://global/content/mozilla.xhtml.

I assume this is the expected failure (I get the same on trunk).
Keywords: fixed1.8.1.17
Verified on Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv: Gecko/2008082909 Firefox/ using test cases here. This is the output in the error console while running test case 8, in comment #57:

Error: result has no properties
Source File: file:///C:/Program%20Files/Mozilla%20Firefox/components/FeedWriter.js
Line: 354

Error: uncaught exception: [Exception... "'[JavaScript Error: "result has no properties" {file: "file:///C:/Program%20Files/Mozilla%20Firefox/components/FeedWriter.js" line: 354}]' when calling method: [nsIFeedWriter::write]"  nsresult: "0x80570021 (NS_ERROR_XPC_JAVASCRIPT_ERROR_WITH_DETAILS)"  location: "JS frame :: chrome://browser/content/feeds/subscribe.js :: SH_init :: line 46"  data: yes]

Error: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsIDOMLocation.href]"  nsresult: "0x80004005 (NS_ERROR_FAILURE)"  location: "native frame :: <unknown filename> :: <TOP_LEVEL> :: line 0"  data: no]
doesnt apply on 1.8.0 from what i can see. If i am mistaking flip wanted1.8.0.x or blocking1.8.0.15 to ? again. Thanks!
Flags: wanted1.8.0.x-
In 20015 test case #8 opens up an alert window, and in 20017 it doesn't.
moz_bug, could you file a new bug on the omissions? Tracking multiple patches in one bug just leads to confusion.
And it seems to me that should block the fx2.0.0.17 release, right?
(In reply to comment #70)
> moz_bug, could you file a new bug on the omissions? Tracking multiple patches
> in one bug just leads to confusion.

I have been convinced that's the right thing to do, instead of continually expanding the scope of this single bug. We'll leave this part of the issue as fixed & verified, and stamp out the others in future releases.

(In reply to comment #71)
> And it seems to me that should block the fx2.0.0.17 release, right?

No, we've waited before, and can continue to do so again.
Depends on: CVE-2008-5504
CC me on it please if you wanst me to fix it.
Group: core-security
Flags: blocking1.8.0.15-
Product: Firefox → Firefox Graveyard
You need to log in before you can comment on or make changes to this bug.