diff --git a/content/xul/templates/src/Makefile.in b/content/xul/templates/src/Makefile.in index 21f49b10d191..89e141f68083 100644 --- a/content/xul/templates/src/Makefile.in +++ b/content/xul/templates/src/Makefile.in @@ -82,7 +82,8 @@ FORCE_STATIC_LIB = 1 include $(topsrcdir)/config/rules.mk LOCAL_INCLUDES = -I$(srcdir)/../../../base/src \ - -I$(srcdir)/../../content/src \ - $(NULL) + -I$(srcdir)/../../content/src \ + -I$(srcdir)/../../../../layout/xul/base/src/tree/src \ + $(NULL) DEFINES += -D_IMPL_NS_LAYOUT diff --git a/content/xul/templates/src/nsXULTreeBuilder.cpp b/content/xul/templates/src/nsXULTreeBuilder.cpp index 1af3745a2d9e..c97468c73571 100644 --- a/content/xul/templates/src/nsXULTreeBuilder.cpp +++ b/content/xul/templates/src/nsXULTreeBuilder.cpp @@ -65,6 +65,7 @@ #include "nsINameSpaceManager.h" #include "nsIDOMClassInfo.h" #include "nsWhitespaceTokenizer.h" +#include "nsTreeContentView.h" // For security check #include "nsIDocument.h" @@ -467,6 +468,9 @@ nsXULTreeBuilder::GetSelection(nsITreeSelection** aSelection) NS_IMETHODIMP nsXULTreeBuilder::SetSelection(nsITreeSelection* aSelection) { + NS_ENSURE_TRUE(!aSelection || + nsTreeContentView::CanTrustTreeSelection(aSelection), + NS_ERROR_DOM_SECURITY_ERR); mSelection = aSelection; return NS_OK; } diff --git a/layout/xul/base/src/tree/public/nsITreeSelection.idl b/layout/xul/base/src/tree/public/nsITreeSelection.idl index 17623d8ff2ed..776d6caf4f75 100644 --- a/layout/xul/base/src/tree/public/nsITreeSelection.idl +++ b/layout/xul/base/src/tree/public/nsITreeSelection.idl @@ -152,3 +152,14 @@ interface nsITreeSelection : nsISupports */ readonly attribute long shiftSelectPivot; }; + +/** + * The following interface is not scriptable and MUST NEVER BE MADE scriptable. + * Native treeselections implement it, and we use this to check whether a + * treeselection is native (and therefore suitable for use by untrusted content). + */ +[uuid(1bd59678-5cb3-4316-b246-31a91b19aabe)] +interface nsINativeTreeSelection : nsITreeSelection +{ + [noscript] void ensureNative(); +}; diff --git a/layout/xul/base/src/tree/src/nsTreeContentView.cpp b/layout/xul/base/src/tree/src/nsTreeContentView.cpp index ae6592d683c4..40e499f494ae 100644 --- a/layout/xul/base/src/tree/src/nsTreeContentView.cpp +++ b/layout/xul/base/src/tree/src/nsTreeContentView.cpp @@ -47,6 +47,7 @@ #include "nsIEventStateManager.h" #include "nsINodeInfo.h" #include "nsIXULSortService.h" +#include "nsContentUtils.h" #include "nsTreeBodyFrame.h" #define NS_ENSURE_NATIVE_COLUMN(_col) \ @@ -201,9 +202,22 @@ nsTreeContentView::GetSelection(nsITreeSelection** aSelection) return NS_OK; } +PRBool +nsTreeContentView::CanTrustTreeSelection(nsISupports* aValue) +{ + // Untrusted content is only allowed to specify known-good views + if (nsContentUtils::IsCallerTrustedForWrite()) + return PR_TRUE; + nsCOMPtr nativeTreeSel = do_QueryInterface(aValue); + return nativeTreeSel && NS_SUCCEEDED(nativeTreeSel->EnsureNative()); +} + NS_IMETHODIMP nsTreeContentView::SetSelection(nsITreeSelection* aSelection) { + NS_ENSURE_TRUE(!aSelection || CanTrustTreeSelection(aSelection), + NS_ERROR_DOM_SECURITY_ERR); + mSelection = aSelection; if (!mSelection || !mUpdateSelection) return NS_OK; diff --git a/layout/xul/base/src/tree/src/nsTreeContentView.h b/layout/xul/base/src/tree/src/nsTreeContentView.h index cdb7f88d5de4..fff63847d37e 100644 --- a/layout/xul/base/src/tree/src/nsTreeContentView.h +++ b/layout/xul/base/src/tree/src/nsTreeContentView.h @@ -82,6 +82,8 @@ class nsTreeContentView : public nsINativeTreeView, NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED NS_DECL_NSIMUTATIONOBSERVER_NODEWILLBEDESTROYED + static PRBool CanTrustTreeSelection(nsISupports* aValue); + protected: // Recursive methods which deal with serializing of nested content. void Serialize(nsIContent* aContent, PRInt32 aParentIndex, PRInt32* aIndex, diff --git a/layout/xul/base/src/tree/src/nsTreeSelection.cpp b/layout/xul/base/src/tree/src/nsTreeSelection.cpp index 305da944eaaf..52272a05bf9e 100644 --- a/layout/xul/base/src/tree/src/nsTreeSelection.cpp +++ b/layout/xul/base/src/tree/src/nsTreeSelection.cpp @@ -280,6 +280,7 @@ DOMCI_DATA(TreeSelection, nsTreeSelection) // QueryInterface implementation for nsBoxObject NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsTreeSelection) NS_INTERFACE_MAP_ENTRY(nsITreeSelection) + NS_INTERFACE_MAP_ENTRY(nsINativeTreeSelection) NS_INTERFACE_MAP_ENTRY(nsISupports) NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(TreeSelection) NS_INTERFACE_MAP_END diff --git a/layout/xul/base/src/tree/src/nsTreeSelection.h b/layout/xul/base/src/tree/src/nsTreeSelection.h index a35e4ff6e945..15d79976e46c 100644 --- a/layout/xul/base/src/tree/src/nsTreeSelection.h +++ b/layout/xul/base/src/tree/src/nsTreeSelection.h @@ -50,7 +50,7 @@ class nsITreeBoxObject; struct nsTreeRange; -class nsTreeSelection : public nsITreeSelection +class nsTreeSelection : public nsINativeTreeSelection { public: nsTreeSelection(nsITreeBoxObject* aTree); @@ -60,6 +60,9 @@ public: NS_DECL_CYCLE_COLLECTION_CLASS(nsTreeSelection) NS_DECL_NSITREESELECTION + // nsINativeTreeSelection: Untrusted code can use us + NS_IMETHOD EnsureNative() { return NS_OK; } + friend struct nsTreeRange; protected: