diff --git a/mozilla/content/base/public/nsContentUtils.h b/mozilla/content/base/public/nsContentUtils.h index 96fa807e581..40af75b49c6 100644 --- a/mozilla/content/base/public/nsContentUtils.h +++ b/mozilla/content/base/public/nsContentUtils.h @@ -101,6 +101,10 @@ public: static PRBool IsCallerChrome(); + static PRBool IsCallerTrustedForRead(); + + static PRBool IsCallerTrustedForWrite(); + /* * Returns true if the nodes are both in the same document or * if neither is in a document. diff --git a/mozilla/content/base/src/nsContentUtils.cpp b/mozilla/content/base/src/nsContentUtils.cpp index 7be7e84462c..12ab39e5a1c 100644 --- a/mozilla/content/base/src/nsContentUtils.cpp +++ b/mozilla/content/base/src/nsContentUtils.cpp @@ -930,6 +930,37 @@ nsContentUtils::IsCallerChrome() return is_caller_chrome; } +static PRBool IsCallerTrustedForCapability(const char* aCapability) +{ + if (nsContentUtils::IsCallerChrome()) + return PR_TRUE; + + // The secman really should handle UniversalXPConnect case, since that + // should include UniversalBrowserRead... doesn't right now, though. + PRBool hasCap; + nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager(); + if (NS_FAILED(ssm->IsCapabilityEnabled(aCapability, &hasCap))) + return PR_FALSE; + if (hasCap) + return PR_TRUE; + + if (NS_FAILED(ssm->IsCapabilityEnabled("UniversalXPConnect", &hasCap))) + return PR_FALSE; + return hasCap; +} + +PRBool +nsContentUtils::IsCallerTrustedForRead() +{ + return IsCallerTrustedForCapability("UniversalBrowserRead"); +} + +PRBool +nsContentUtils::IsCallerTrustedForWrite() +{ + return IsCallerTrustedForCapability("UniversalBrowserWrite"); +} + // static PRBool nsContentUtils::InSameDoc(nsIDOMNode* aNode, nsIDOMNode* aOther) diff --git a/mozilla/content/xul/templates/src/nsXULTreeBuilder.cpp b/mozilla/content/xul/templates/src/nsXULTreeBuilder.cpp index 736ab653ee6..1ef433840e4 100644 --- a/mozilla/content/xul/templates/src/nsXULTreeBuilder.cpp +++ b/mozilla/content/xul/templates/src/nsXULTreeBuilder.cpp @@ -82,7 +82,7 @@ */ class nsXULTreeBuilder : public nsXULTemplateBuilder, public nsIXULTreeBuilder, - public nsITreeView + public nsINativeTreeView { public: // nsISupports @@ -93,6 +93,8 @@ public: // nsITreeView NS_DECL_NSITREEVIEW + // nsINativeTreeView: Untrusted code can use us + NS_IMETHOD EnsureNative() { return NS_OK; } virtual void DocumentWillBeDestroyed(nsIDocument *aDocument); diff --git a/mozilla/extensions/sql/base/src/mozSqlResult.h b/mozilla/extensions/sql/base/src/mozSqlResult.h index 7c352fa4e38..7af2e1362e8 100644 --- a/mozilla/extensions/sql/base/src/mozSqlResult.h +++ b/mozilla/extensions/sql/base/src/mozSqlResult.h @@ -293,7 +293,7 @@ class mozSqlResult : public mozISqlResult, public mozISqlDataSource, public nsIRDFDataSource, public nsIRDFRemoteDataSource, - public nsITreeView + public nsINativeTreeView { public: mozSqlResult(mozISqlConnection* aConnection, @@ -328,6 +328,8 @@ class mozSqlResult : public mozISqlResult, NS_DECL_NSIRDFREMOTEDATASOURCE NS_DECL_NSITREEVIEW + // nsINativeTreeView: Untrusted code can use us + NS_IMETHOD EnsureNative() { return NS_OK; } friend class mozSqlResultEnumerator; friend class mozSqlResultStream; diff --git a/mozilla/layout/xul/base/src/tree/public/nsITreeView.idl b/mozilla/layout/xul/base/src/tree/public/nsITreeView.idl index 4a0c6e73178..12fc88cb28b 100644 --- a/mozilla/layout/xul/base/src/tree/public/nsITreeView.idl +++ b/mozilla/layout/xul/base/src/tree/public/nsITreeView.idl @@ -225,3 +225,14 @@ interface nsITreeView : nsISupports */ void performActionOnCell(in wstring action, in long row, in nsITreeColumn col); }; + +/** + * The following interface is not scriptable and MUST NEVER BE MADE scriptable. + * Native treeviews implement it, and we use this to check whether a treeview + * is native (and therefore suitable for use by untrusted content). + */ +[uuid(38e0b44d-fa08-458c-83fb-3e10b12aeb45)] +interface nsINativeTreeView : nsITreeView +{ + [noscript] void ensureNative(); +}; diff --git a/mozilla/layout/xul/base/src/tree/src/nsTreeBoxObject.cpp b/mozilla/layout/xul/base/src/tree/src/nsTreeBoxObject.cpp index 0168e622f7b..46986126912 100644 --- a/mozilla/layout/xul/base/src/tree/src/nsTreeBoxObject.cpp +++ b/mozilla/layout/xul/base/src/tree/src/nsTreeBoxObject.cpp @@ -48,6 +48,8 @@ #include "nsINodeInfo.h" #include "nsXULAtoms.h" #include "nsChildIterator.h" +#include "nsContentUtils.h" +#include "nsDOMError.h" class nsTreeBoxObject : public nsPITreeBoxObject, public nsBoxObject { @@ -187,6 +189,14 @@ NS_IMETHODIMP nsTreeBoxObject::GetView(nsITreeView * *aView) NS_IMETHODIMP nsTreeBoxObject::SetView(nsITreeView * aView) { + // Untrusted content is only allowed to specify known-good views + if (!nsContentUtils::IsCallerTrustedForWrite()) { + nsCOMPtr nativeTreeView = do_QueryInterface(aView); + if (!nativeTreeView || NS_FAILED(nativeTreeView->EnsureNative())) + // XXX ERRMSG need a good error here for developers + return NS_ERROR_DOM_SECURITY_ERR; + } + nsITreeBoxObject* body = GetTreeBody(); if (body) { body->SetView(aView); diff --git a/mozilla/layout/xul/base/src/tree/src/nsTreeContentView.h b/mozilla/layout/xul/base/src/tree/src/nsTreeContentView.h index 35382744029..d9046f98edd 100644 --- a/mozilla/layout/xul/base/src/tree/src/nsTreeContentView.h +++ b/mozilla/layout/xul/base/src/tree/src/nsTreeContentView.h @@ -50,7 +50,7 @@ nsresult NS_NewTreeContentView(nsITreeContentView** aResult); -class nsTreeContentView : public nsITreeView, +class nsTreeContentView : public nsINativeTreeView, public nsITreeContentView, public nsStubDocumentObserver { @@ -64,6 +64,8 @@ class nsTreeContentView : public nsITreeView, NS_DECL_ISUPPORTS NS_DECL_NSITREEVIEW + // nsINativeTreeView: Untrusted code can use us + NS_IMETHOD EnsureNative() { return NS_OK; } NS_DECL_NSITREECONTENTVIEW