Closed Bug 343594 Opened 18 years ago Closed 18 years ago

Native DOM methods can be hijacked across domain security boundaries, allowing cross-domain scripting

Categories

(Core :: Security, defect)

1.8 Branch
defect
Not set
major

Tracking

()

RESOLVED FIXED

People

(Reporter: thor, Assigned: mrbkap)

References

()

Details

(Keywords: fixed1.8.0.5, fixed1.8.1, regression, Whiteboard: [sg:high XSS] fixed by 339918+340537 (not 1.7/aviary))

Attachments

(2 files, 1 obsolete file)

User-Agent:       Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.4) Gecko/20060508 Firefox/1.5.0.4
Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.4) Gecko/20060508 Firefox/1.5.0.4

A page on foo.com can load bar.com in an IFRAME or OBJECT element and then change the native DOM methods inside that third-party document, despite that this should be prevented through domain security boundaries. This allows cross-domain scripting.

I originally posted this information in a post to the Bugtraq mailing list, http://groups.google.dk/group/mailing.unix.bugtraq/msg/51c045589d2ec1ee - from that post:

Ordinarily, when you have a window object containing a document from a thirdparty domain, such as <iframe id="thirdparty" src="http://google.com"></iframe>, you are not allowed to reference any kind of objects inside this window. Using a DOM 0 approach, window.frames[0].contentDocument will give you a security exception. However, reading the contentDocument property of the DOM element instead of the through the frames collection will give you a reference to the document object inside the thirdparty domain and even allow you to overwrite native DOM methods without throwing a security exception, such as document.getElementById("thirdparty").contentDocument.getElementById=function(s){alert(s)}. This also holds true for window.frames[0].document.getElementsByTagName and any other methods on the document object.

Functionally, the document and contentDocument properties both reference the same object and should obey the same security context rules, however Firefox differentiates based on how you reference that object and thus allows you to overwrite native DOM methods on a thirdparty domain, broadening the potential attack scope by allowing you to interfere with the operations of existing script code inside that thirdparty document. 

Reproducible: Always

Steps to Reproduce:
1. Create an HTML document on foo.com that contains an IFRAME or OBJECT referencing bar.com
2. Reference the contentDocument object on the IFRAME or OBJECT element
3. This should throw a security exception, but does not

Actual Results:  
I was able to overwrite any native DOM methods on the third-party document, such as getElementById and getElementsByTagName, thereby interfering with the ordinary operation of script code in that document.

Expected Results:  
Firefox should throw a security exception when I try to reference the contentDocument object on any kind of third-party document. This is also the actual result in Internet Explorer 4, 5 and 6.
Version: unspecified → 1.5.0.x Branch
Is the Core product the proper category to use instead of just Firefox? Without even testing it, I'll wager that any other products using the rendering and script engine are also affected, such as Mozilla/Seamonkey
Assignee: nobody → dveditz
Product: Firefox → Core
QA Contact: firefox → toolkit
Version: 1.5.0.x Branch → 1.8 Branch
Attached file testcase that does NOT show the bug (obsolete) —
I wrote this testcase to try to demonstrate what you describe, but it doesn't show the bug.  I get the error:

Error: uncaught exception: Permission denied to set property HTMLDocument.getElementById

in both Firefox 1.5.0.4 and on the trunk.


Could you attach the testcase that you used to see that the bug is present?
Attachment #228096 - Attachment is obsolete: true
This testcase demonstrates the described bug, which turns out to be patched in bug 339918 (found by jruderman testing the new js1.7 __iterator__ feature on the trunk -- thanks to mrbkap for catching the similarity).

When you try to set properties on the document from inside a function (as in dbaron's initial testcase) the security checks work as designed. From top-level there's no Function object to check and the needsSecurityCheck() code gets a little confused.

IMPORTANT TESTING NOTE:This testcase must be loaded from another domain to demonstrate the problem (and fix). When both outer and inner frames are loaded from bugzilla they can rightfully muck with each other's documents. You can download the test locally, or login to bugzilla via the physical machine name (currently that would be https://recluse.mozilla.org/show_bug.cgi?id=343594 )
Not sure of the severity here... The outer frame can read and replace properties and methods directly on the inner document, but exceptions are thrown if it tries to call any of the document methods to alter the DOM. Calling f.contentDocument.getElementById("somenode") to find a node fails, but the IE-compatibility hack f.contentDocument.all.somenode works. When I tried reading or setting the value of an input element I was stopped, but I haven't tried other element types.

Can't get at document.cookie, document.domain, document.location... those have separate security checks. I can read/set pure javascript properties or override things that are part of nsIDOMDocument, but nothing that's nsIDOMHTMLDocument.

At the very least this could be used as an intentional cross-domain communication channel. But since the inserted functions can be called by the inner frame you could booby trap some common function to do the spying/altering indirectly.
Assignee: dveditz → mrbkap
Status: UNCONFIRMED → NEW
Ever confirmed: true
Whiteboard: [sg:high XSS] fixed by 339918
Depends on: 339918
Flags: blocking1.8.1?
Flags: blocking1.8.0.5?
mrbkap checked in the 339918 fix into the 1.8 branch (Firefox 2), should get the 1.8.0 branch (Firefox 1.5.0.5) today. The fix was checked into the trunk in early June (caused regression bug 340537, also fixed on trunk and 1.8 branch).
Status: NEW → RESOLVED
Closed: 18 years ago
Flags: blocking1.8.0.5? → blocking1.8.0.5+
Keywords: fixed1.8.1
Resolution: --- → FIXED
Whiteboard: [sg:high XSS] fixed by 339918 → [sg:high XSS] fixed by 339918+340537
I checked the fixes for this bug into the 1.8.0 branch.
Keywords: fixed1.8.0.5
This bug does not affect Firefox 1.0.x or Mozilla 1.7.X
Flags: blocking1.7.14-
Flags: blocking-aviary1.0.9-
Keywords: regression
Whiteboard: [sg:high XSS] fixed by 339918+340537 → [sg:high XSS] fixed by 339918+340537 (not 1.7/aviary)
I just got back from vacation, good to see that you figured out the function/Global scope differences and patched this in the 1.5.0.5 release.

Are there any open bugs on needsSecurityCheck relying on an existing Function object? In my opinion, you shouldn't rely on a Function object existing for the checks to suceed properly.
(In reply to comment #9)
> Are there any open bugs on needsSecurityCheck relying on an existing Function
> object? In my opinion, you shouldn't rely on a Function object existing for the
> checks to suceed properly.

In general, they don't. The bug that caused this was caused by an optimization to avoid doing extra security checks. That optimization has now been fixed to not require a function object to work 'correctly'.
pvnick is doing a bit of research on XSS and also gathering up bugs with security related test cases to help add to the regression/certification test suites.  adding him to the cc list in these...
Group: security
Flags: blocking1.8.1?
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: