diff --git a/content/base/public/nsContentUtils.h b/content/base/public/nsContentUtils.h index 02f67336364..6c38759d810 100644 --- a/content/base/public/nsContentUtils.h +++ b/content/base/public/nsContentUtils.h @@ -166,6 +166,9 @@ public: const nsAString& aValue); static void Shutdown(); + + // Checks if two nodes live in document coming from the same origin + static nsresult CheckSameOrigin(nsIDOMNode* aNode1, nsIDOMNode* aNode2); private: static nsresult doReparentContentWrapper(nsIContent *aChild, diff --git a/content/base/src/nsContentUtils.cpp b/content/base/src/nsContentUtils.cpp index 5200ab36660..847db2f7e15 100644 --- a/content/base/src/nsContentUtils.cpp +++ b/content/base/src/nsContentUtils.cpp @@ -49,6 +49,10 @@ #include "nsIDocument.h" #include "nsINodeInfo.h" #include "nsReadableUtils.h" +#include "nsIDOMDocument.h" +#include "nsIURI.h" +#include "nsIScriptSecurityManager.h" +#include "nsDOMError.h" #include "nsIJSContextStack.h" #include "nsIDocShell.h" @@ -350,6 +354,58 @@ nsContentUtils::GetClassInfoInstance(nsDOMClassInfoID aID) return sDOMScriptObjectFactory->GetClassInfoInstance(aID); } +// static +nsresult +nsContentUtils::CheckSameOrigin(nsIDOMNode* aNode1, nsIDOMNode* aNode2) +{ + nsCOMPtr doc1 = do_QueryInterface(aNode1); + if (!doc1) { + // Make sure that this is a real node. + nsCOMPtr cont1 = do_QueryInterface(aNode1); + if (!cont1) { + return NS_ERROR_DOM_SECURITY_ERR; + } + + nsCOMPtr domDoc1; + aNode1->GetOwnerDocument(getter_AddRefs(domDoc1)); + doc1 = do_QueryInterface(domDoc1); + if (!doc1) { + return NS_ERROR_FAILURE; + } + } + + nsCOMPtr doc2 = do_QueryInterface(aNode2); + if (!doc2) { + // Make sure that this is a real node. + nsCOMPtr cont2 = do_QueryInterface(aNode2); + if (!cont2) { + return NS_ERROR_DOM_SECURITY_ERR; + } + + nsCOMPtr domDoc2; + aNode2->GetOwnerDocument(getter_AddRefs(domDoc2)); + doc2 = do_QueryInterface(domDoc2); + if (!doc2) { + return NS_ERROR_FAILURE; + } + } + + if (doc1 == doc2) + return NS_OK; + + nsCOMPtr uri1; + doc1->GetDocumentURL(getter_AddRefs(uri1)); + nsCOMPtr uri2; + doc2->GetDocumentURL(getter_AddRefs(uri2)); + + nsresult rv = NS_OK; + nsCOMPtr securityManager = + do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + + return securityManager->CheckSameOriginURI(uri1, uri2); +} + // static nsresult nsContentUtils::doReparentContentWrapper(nsIContent *aChild, diff --git a/content/base/src/nsDocument.cpp b/content/base/src/nsDocument.cpp index 5d695ccfba0..c0812cc987a 100644 --- a/content/base/src/nsDocument.cpp +++ b/content/base/src/nsDocument.cpp @@ -2698,6 +2698,12 @@ nsDocument::CreateTreeWalker(nsIDOMNode *aRoot, PRBool aEntityReferenceExpansion, nsIDOMTreeWalker **_retval) { + *_retval = nsnull; + + nsresult rv = nsContentUtils::CheckSameOrigin(this, aRoot); + if(NS_FAILED(rv)) + return rv; + return NS_NewTreeWalker(aRoot, aWhatToShow, aFilter, diff --git a/content/base/src/nsTreeWalker.cpp b/content/base/src/nsTreeWalker.cpp index 7991a312b7c..b89ccf23d9d 100644 --- a/content/base/src/nsTreeWalker.cpp +++ b/content/base/src/nsTreeWalker.cpp @@ -159,6 +159,11 @@ NS_IMETHODIMP nsTreeWalker::GetCurrentNode(nsIDOMNode * *aCurrentNode) NS_IMETHODIMP nsTreeWalker::SetCurrentNode(nsIDOMNode * aCurrentNode) { NS_ENSURE_TRUE(aCurrentNode, NS_ERROR_DOM_NOT_SUPPORTED_ERR); + + nsresult rv = nsContentUtils::CheckSameOrigin(mRoot, aCurrentNode); + if(NS_FAILED(rv)) + return rv; + mCurrentNode = aCurrentNode; return NS_OK; } diff --git a/content/xul/document/src/nsXULDocument.cpp b/content/xul/document/src/nsXULDocument.cpp index 12bc265c9d2..2fc03ef537f 100644 --- a/content/xul/document/src/nsXULDocument.cpp +++ b/content/xul/document/src/nsXULDocument.cpp @@ -3214,6 +3214,12 @@ nsXULDocument::CreateTreeWalker(nsIDOMNode *aRoot, PRBool aEntityReferenceExpansion, nsIDOMTreeWalker **_retval) { + *_retval = nsnull; + + nsresult rv = nsContentUtils::CheckSameOrigin(this, aRoot); + if(NS_FAILED(rv)) + return rv; + return NS_NewTreeWalker(aRoot, aWhatToShow, aFilter,