Bug 546857 Part 6: Disable XUL for pages, unless user specifically opts in for domain. r=jst a=blocker

This commit is contained in:
Jonas Sicking 2010-08-19 16:12:46 -07:00
Родитель a66617aa2d
Коммит 0145c9b59e
15 изменённых файлов: 158 добавлений и 43 удалений

Просмотреть файл

@ -126,6 +126,9 @@ NS_NewMathMLElement(nsIContent** aResult,
#ifdef MOZ_XUL
nsresult
NS_NewXULElement(nsIContent** aResult, already_AddRefed<nsINodeInfo> aNodeInfo);
void
NS_TrustedNewXULElement(nsIContent** aResult, already_AddRefed<nsINodeInfo> aNodeInfo);
#endif
#ifdef MOZ_SVG

Просмотреть файл

@ -610,6 +610,11 @@ public:
return sPrefBranch;
}
// Get a permission-manager setting for the given uri and type.
// If the pref doesn't exist or if it isn't ALLOW_ACTION, PR_FALSE is
// returned, otherwise PR_TRUE is returned.
static PRBool IsSitePermAllow(nsIURI* aURI, const char* aType);
static nsILineBreaker* LineBreaker()
{
return sLineBreaker;

Просмотреть файл

@ -119,8 +119,8 @@ class Element;
#define NS_IDOCUMENT_IID \
{ 0x0218352e, 0x9ddf, 0x43b0, \
{ 0xb6, 0x1d, 0xd3, 0x1a, 0x47, 0x7a, 0xfd, 0x89 } }
{ 0xbd862a79, 0xc31b, 0x419b, \
{ 0x92, 0x90, 0xa0, 0x77, 0x08, 0x62, 0xd4, 0xc4 } }
// Flag for AddStyleSheet().
#define NS_STYLESHEET_FROM_CATALOG (1 << 0)
@ -1291,6 +1291,20 @@ public:
PRBool IsDNSPrefetchAllowed() const { return mAllowDNSPrefetch; }
/**
* Returns PR_TRUE if this document is allowed to contain XUL element and
* use non-builtin XBL bindings.
*/
PRBool AllowXULXBL() {
return mAllowXULXBL == eTriTrue ? PR_TRUE :
mAllowXULXBL == eTriFalse ? PR_FALSE :
InternalAllowXULXBL();
}
void ForceEnableXULXBL() {
mAllowXULXBL = eTriTrue;
}
/**
* PR_TRUE when this document is a static clone of a normal document.
* For example print preview and printing use static documents.
@ -1470,6 +1484,9 @@ protected:
// Never ever call this. Only call GetScriptHandlingObject!
virtual nsIScriptGlobalObject* GetScriptHandlingObjectInternal() const = 0;
// Never ever call this. Only call AllowXULXBL!
virtual PRBool InternalAllowXULXBL() = 0;
/**
* These methods should be called before and after dispatching
* a mutation event.
@ -1553,6 +1570,12 @@ protected:
PRPackedBool mIsRegularHTML;
PRPackedBool mIsXUL;
enum {
eTriUnset = 0,
eTriFalse,
eTriTrue
} mAllowXULXBL;
// True if we're loaded as data and therefor has any dangerous stuff, such
// as scripts and plugins, disabled.
PRPackedBool mLoadedAsData;

Просмотреть файл

@ -153,6 +153,7 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_XTFSERVICE_CID);
#include "nsIPrivateDOMEvent.h"
#include "nsXULPopupManager.h"
#include "nsIPermissionManager.h"
#include "nsIContentPrefService.h"
#include "nsIScriptObjectPrincipal.h"
#include "nsIRunnable.h"
#include "nsDOMJSUtils.h"
@ -2806,6 +2807,20 @@ nsContentUtils::AddIntPrefVarCache(const char *aPref,
RegisterPrefCallback(aPref, IntVarChanged, data);
}
PRBool
nsContentUtils::IsSitePermAllow(nsIURI* aURI, const char* aType)
{
nsCOMPtr<nsIPermissionManager> permMgr =
do_GetService("@mozilla.org/permissionmanager;1");
NS_ENSURE_TRUE(permMgr, PR_FALSE);
PRUint32 perm;
nsresult rv = permMgr->TestPermission(aURI, aType, &perm);
NS_ENSURE_SUCCESS(rv, PR_FALSE);
return perm == nsIPermissionManager::ALLOW_ACTION;
}
static const char *gEventNames[] = {"event"};
static const char *gSVGEventNames[] = {"evt"};
// for b/w compat, the first name to onerror is still 'event', even though it

Просмотреть файл

@ -272,6 +272,10 @@ nsDOMParser::ParseFromStream(nsIInputStream *stream,
nsCOMPtr<nsIDocument> document(do_QueryInterface(domDocument));
if (!document) return NS_ERROR_FAILURE;
if (nsContentUtils::IsSystemPrincipal(mOriginalPrincipal)) {
document->ForceEnableXULXBL();
}
rv = document->StartDocumentLoad(kLoadAsData, parserChannel,
nsnull, nsnull,
getter_AddRefs(listener),

Просмотреть файл

@ -3801,6 +3801,30 @@ nsDocument::ScriptLoader()
return mScriptLoader;
}
PRBool
nsDocument::InternalAllowXULXBL()
{
if (nsContentUtils::IsSystemPrincipal(NodePrincipal())) {
mAllowXULXBL = eTriTrue;
return PR_TRUE;
}
nsCOMPtr<nsIURI> princURI;
NodePrincipal()->GetURI(getter_AddRefs(princURI));
if (!princURI) {
mAllowXULXBL = eTriFalse;
return PR_FALSE;
}
if (nsContentUtils::IsSitePermAllow(princURI, "allowXULXBL")) {
mAllowXULXBL = eTriTrue;
return PR_TRUE;
}
mAllowXULXBL = eTriFalse;
return PR_FALSE;
}
// Note: We don't hold a reference to the document observer; we assume
// that it has a live reference to the document.
void

Просмотреть файл

@ -1049,6 +1049,7 @@ protected:
virtual nsPIDOMWindow *GetWindowInternal();
virtual nsPIDOMWindow *GetInnerWindowInternal();
virtual nsIScriptGlobalObject* GetScriptHandlingObjectInternal() const;
virtual PRBool InternalAllowXULXBL();
#define NS_DOCUMENT_NOTIFY_OBSERVERS(func_, params_) \
NS_OBSERVER_ARRAY_NOTIFY_XPCOM_OBSERVERS(mObservers, nsIDocumentObserver, \

Просмотреть файл

@ -13,8 +13,8 @@
<iframe type="content" id="xhtml4" src="data:text/xml,&lt;html xmlns='http://www.w3.org/1999/xhtml'/>"/>
<iframe type="content" id="xhtml5" src="data:text/xml,&lt;html xmlns='http://www.w3.org/1999/xhtml'&gt;&lt;head/>&lt;/html&gt;"/>
<iframe type="content" id="xhtml6" src="data:text/xml,&lt;html xmlns='http://www.w3.org/1999/xhtml'&gt;&lt;head&gt;&lt;style/>&lt;/head&gt;&lt;/html&gt;"/>
<iframe type="content" id="xul1" src="data:application/vnd.mozilla.xul+xml,&lt;window xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul' title='Test'/>"/>
<iframe type="content" id="xul2" src="data:application/vnd.mozilla.xul+xml,&lt;window xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul' title='Test'/>"/>
<iframe id="xul1" src="data:application/vnd.mozilla.xul+xml,&lt;window xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul' title='Test'/>"/>
<iframe id="xul2" src="data:application/vnd.mozilla.xul+xml,&lt;window xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul' title='Test'/>"/>
<iframe type="content" id="svg1" src="data:text/xml,&lt;svg xmlns='http://www.w3.org/2000/svg'&gt;&lt;title id='t'&gt;Test&lt;/title&gt;&lt;/svg&gt;"/>
<iframe type="content" id="svg2" src="data:text/xml,&lt;svg xmlns='http://www.w3.org/2000/svg'&gt;&lt;title id='t'&gt;Test&lt;/title&gt;&lt;/svg&gt;"/>

Просмотреть файл

@ -1064,6 +1064,21 @@ static PRBool SchemeIs(nsIURI* aURI, const char* aScheme)
return NS_SUCCEEDED(baseURI->SchemeIs(aScheme, &isScheme)) && isScheme;
}
static PRBool
IsSystemOrChromeURLPrincipal(nsIPrincipal* aPrincipal)
{
if (nsContentUtils::IsSystemPrincipal(aPrincipal)) {
return PR_TRUE;
}
nsCOMPtr<nsIURI> uri;
aPrincipal->GetURI(getter_AddRefs(uri));
NS_ENSURE_TRUE(uri, PR_FALSE);
PRBool isChrome = PR_FALSE;
return NS_SUCCEEDED(uri->SchemeIs("chrome", &isChrome)) && isChrome;
}
NS_IMETHODIMP
nsXBLService::LoadBindingDocumentInfo(nsIContent* aBoundElement,
nsIDocument* aBoundDocument,
@ -1094,19 +1109,19 @@ nsXBLService::LoadBindingDocumentInfo(nsIContent* aBoundElement,
aBoundDocument);
NS_ENSURE_SUCCESS(rv, rv);
// Also make sure that we're same-origin with the bound document
// except if the stylesheet has the system principal.
PRBool isSystem;
rv = nsContentUtils::GetSecurityManager()->
IsSystemPrincipal(aOriginPrincipal, &isSystem);
NS_ENSURE_SUCCESS(rv, rv);
if (!IsSystemOrChromeURLPrincipal(aOriginPrincipal)) {
// Also make sure that we're same-origin with the bound document
// except if the stylesheet has the system principal.
if (!(gAllowDataURIs && SchemeIs(aBindingURI, "data")) &&
!SchemeIs(aBindingURI, "chrome")) {
rv = aBoundDocument->NodePrincipal()->CheckMayLoad(aBindingURI,
PR_TRUE);
NS_ENSURE_SUCCESS(rv, rv);
}
if (!isSystem &&
!(gAllowDataURIs && SchemeIs(aBindingURI, "data")) &&
!SchemeIs(aBindingURI, "chrome")) {
rv = aBoundDocument->NodePrincipal()->CheckMayLoad(aBindingURI,
PR_TRUE);
NS_ENSURE_SUCCESS(rv, rv);
// Finally check if this document is allowed to use XBL at all.
NS_ENSURE_TRUE(aBoundDocument->AllowXULXBL(),
NS_ERROR_NOT_AVAILABLE);
}
}

Просмотреть файл

@ -347,17 +347,26 @@ NS_NewXULElement(nsIContent** aResult, already_AddRefed<nsINodeInfo> aNodeInfo)
{
NS_PRECONDITION(aNodeInfo.get(), "need nodeinfo for non-proto Create");
*aResult = nsnull;
nsIDocument* doc = aNodeInfo.get()->GetDocument();
if (doc && !doc->AllowXULXBL()) {
nsCOMPtr<nsINodeInfo> ni = aNodeInfo;
return NS_ERROR_NOT_AVAILABLE;
}
// Create an nsXULElement with the specified namespace and tag.
nsXULElement* element = new nsXULElement(aNodeInfo);
NS_ENSURE_TRUE(element, NS_ERROR_OUT_OF_MEMORY);
NS_ADDREF(*aResult = element);
NS_ADDREF(*aResult = new nsXULElement(aNodeInfo));
return NS_OK;
}
void
NS_TrustedNewXULElement(nsIContent** aResult, already_AddRefed<nsINodeInfo> aNodeInfo)
{
NS_PRECONDITION(aNodeInfo.get(), "need nodeinfo for non-proto Create");
// Create an nsXULElement with the specified namespace and tag.
NS_ADDREF(*aResult = new nsXULElement(aNodeInfo));
}
//----------------------------------------------------------------------
// nsISupports interface

Просмотреть файл

@ -697,6 +697,8 @@ protected:
friend nsresult
NS_NewXULElement(nsIContent** aResult, nsINodeInfo *aNodeInfo);
friend void
NS_TrustedNewXULElement(nsIContent** aResult, nsINodeInfo *aNodeInfo);
static already_AddRefed<nsXULElement>
Create(nsXULPrototypeElement* aPrototype, nsINodeInfo *aNodeInfo,

Просмотреть файл

@ -251,6 +251,8 @@ nsXULDocument::nsXULDocument(void)
mIsXUL = PR_TRUE;
mDelayFrameLoaderInitialization = PR_TRUE;
mAllowXULXBL = eTriTrue;
}
nsXULDocument::~nsXULDocument()

Просмотреть файл

@ -48,6 +48,7 @@
#include "nsIURL.h"
#include "nsNodeInfo.h"
#include "nsNodeInfoManager.h"
#include "nsIScriptSecurityManager.h"
#include "nsString.h"
#include "nsContentCID.h"
#include "prprf.h"
@ -156,6 +157,30 @@ nsContentDLF::~nsContentDLF()
NS_IMPL_ISUPPORTS1(nsContentDLF,
nsIDocumentLoaderFactory)
PRBool
MayUseXULXBL(nsIChannel* aChannel)
{
nsIScriptSecurityManager *securityManager =
nsContentUtils::GetSecurityManager();
if (!securityManager) {
return PR_FALSE;
}
nsCOMPtr<nsIPrincipal> principal;
securityManager->GetChannelPrincipal(aChannel, getter_AddRefs(principal));
NS_ENSURE_TRUE(principal, PR_FALSE);
if (nsContentUtils::IsSystemPrincipal(principal)) {
return PR_TRUE;
}
nsCOMPtr<nsIURI> uri;
principal->GetURI(getter_AddRefs(uri));
NS_ENSURE_TRUE(uri, PR_FALSE);
return nsContentUtils::IsSitePermAllow(uri, "allowXULXBL");
}
NS_IMETHODIMP
nsContentDLF::CreateInstance(const char* aCommand,
nsIChannel* aChannel,
@ -278,8 +303,9 @@ nsContentDLF::CreateInstance(const char* aCommand,
// Try XUL
typeIndex = 0;
while (gXULTypes[typeIndex]) {
if (0 == PL_strcmp(gXULTypes[typeIndex++], aContentType)) {
return CreateXULDocument(aCommand,
if (0 == PL_strcmp(gXULTypes[typeIndex++], aContentType) &&
MayUseXULXBL(aChannel)) {
return CreateXULDocument(aCommand,
aChannel, aLoadGroup,
aContentType, aContainer,
aExtraInfo, aDocListener, aDocViewer);

Просмотреть файл

@ -2163,8 +2163,6 @@ nsGfxScrollFrameInner::CreateAnonymousContent(nsTArray<nsIContent*>& aElements)
}
}
nsresult rv;
nsNodeInfoManager *nodeInfoManager =
presContext->Document()->NodeInfoManager();
nsCOMPtr<nsINodeInfo> nodeInfo;
@ -2174,9 +2172,7 @@ nsGfxScrollFrameInner::CreateAnonymousContent(nsTArray<nsIContent*>& aElements)
if (canHaveHorizontal) {
nsCOMPtr<nsINodeInfo> ni = nodeInfo;
rv = NS_NewElement(getter_AddRefs(mHScrollbarContent),
kNameSpaceID_XUL, ni.forget(), PR_FALSE);
NS_ENSURE_SUCCESS(rv, rv);
NS_TrustedNewXULElement(getter_AddRefs(mHScrollbarContent), ni.forget());
mHScrollbarContent->SetAttr(kNameSpaceID_None, nsGkAtoms::orient,
NS_LITERAL_STRING("horizontal"), PR_FALSE);
mHScrollbarContent->SetAttr(kNameSpaceID_None, nsGkAtoms::clickthrough,
@ -2187,9 +2183,7 @@ nsGfxScrollFrameInner::CreateAnonymousContent(nsTArray<nsIContent*>& aElements)
if (canHaveVertical) {
nsCOMPtr<nsINodeInfo> ni = nodeInfo;
rv = NS_NewElement(getter_AddRefs(mVScrollbarContent),
kNameSpaceID_XUL, ni.forget(), PR_FALSE);
NS_ENSURE_SUCCESS(rv, rv);
NS_TrustedNewXULElement(getter_AddRefs(mVScrollbarContent), ni.forget());
mVScrollbarContent->SetAttr(kNameSpaceID_None, nsGkAtoms::orient,
NS_LITERAL_STRING("vertical"), PR_FALSE);
mVScrollbarContent->SetAttr(kNameSpaceID_None, nsGkAtoms::clickthrough,
@ -2204,9 +2198,7 @@ nsGfxScrollFrameInner::CreateAnonymousContent(nsTArray<nsIContent*>& aElements)
kNameSpaceID_XUL);
NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
rv = NS_NewXULElement(getter_AddRefs(mScrollCornerContent),
nodeInfo.forget());
NS_ENSURE_SUCCESS(rv, rv);
NS_TrustedNewXULElement(getter_AddRefs(mScrollCornerContent), nodeInfo.forget());
nsAutoString dir;
switch (resizeStyle) {
@ -2239,9 +2231,7 @@ nsGfxScrollFrameInner::CreateAnonymousContent(nsTArray<nsIContent*>& aElements)
else if (canHaveHorizontal && canHaveVertical) {
nodeInfo = nodeInfoManager->GetNodeInfo(nsGkAtoms::scrollcorner, nsnull,
kNameSpaceID_XUL);
rv = NS_NewElement(getter_AddRefs(mScrollCornerContent),
kNameSpaceID_XUL, nodeInfo.forget(), PR_FALSE);
NS_ENSURE_SUCCESS(rv, rv);
NS_TrustedNewXULElement(getter_AddRefs(mScrollCornerContent), nodeInfo.forget());
if (!aElements.AppendElement(mScrollCornerContent))
return NS_ERROR_OUT_OF_MEMORY;
}

Просмотреть файл

@ -127,11 +127,7 @@ nsVideoFrame::CreateAnonymousContent(nsTArray<nsIContent*>& aElements)
kNameSpaceID_XUL);
NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
nsresult rv = NS_NewElement(getter_AddRefs(mVideoControls),
kNameSpaceID_XUL,
nodeInfo.forget(),
PR_FALSE);
NS_ENSURE_SUCCESS(rv, rv);
NS_TrustedNewXULElement(getter_AddRefs(mVideoControls), nodeInfo.forget());
if (!aElements.AppendElement(mVideoControls))
return NS_ERROR_OUT_OF_MEMORY;