Add same-origin checks in a few DOM methods. Patch by me and jst.

b=156452, r=jst/me, sr=bz, a=pending
This commit is contained in:
sicking%bigfoot.com 2002-07-16 13:09:15 +00:00
Родитель ab62a85dde
Коммит 17bc6e66e4
18 изменённых файлов: 270 добавлений и 47 удалений

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

@ -170,6 +170,9 @@ public:
// Checks if two nodes live in document coming from the same origin // Checks if two nodes live in document coming from the same origin
static nsresult CheckSameOrigin(nsIDOMNode* aNode1, nsIDOMNode* aNode2); static nsresult CheckSameOrigin(nsIDOMNode* aNode1, nsIDOMNode* aNode2);
// Check if the (JS) caller can access aNode.
static PRBool CanCallerAccess(nsIDOMNode *aNode);
private: private:
static nsresult doReparentContentWrapper(nsIContent *aChild, static nsresult doReparentContentWrapper(nsIContent *aChild,
nsIDocument *aNewDocument, nsIDocument *aNewDocument,

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

@ -356,7 +356,7 @@ nsContentUtils::GetClassInfoInstance(nsDOMClassInfoID aID)
// static // static
nsresult nsresult
nsContentUtils::CheckSameOrigin(nsIDOMNode* aNode1, nsIDOMNode* aNode2) nsContentUtils::CheckSameOrigin(nsIDOMNode *aNode1, nsIDOMNode *aNode2)
{ {
nsCOMPtr<nsIDocument> doc1 = do_QueryInterface(aNode1); nsCOMPtr<nsIDocument> doc1 = do_QueryInterface(aNode1);
if (!doc1) { if (!doc1) {
@ -368,10 +368,12 @@ nsContentUtils::CheckSameOrigin(nsIDOMNode* aNode1, nsIDOMNode* aNode2)
nsCOMPtr<nsIDOMDocument> domDoc1; nsCOMPtr<nsIDOMDocument> domDoc1;
aNode1->GetOwnerDocument(getter_AddRefs(domDoc1)); aNode1->GetOwnerDocument(getter_AddRefs(domDoc1));
doc1 = do_QueryInterface(domDoc1); if (!domDoc1) {
if (!doc1) { // aNode1 is not part of a document, let any caller access it.
return NS_ERROR_FAILURE; return NS_OK;
} }
doc1 = do_QueryInterface(domDoc1);
NS_ASSERTION(doc1, "QI to nsIDocument failed");
} }
nsCOMPtr<nsIDocument> doc2 = do_QueryInterface(aNode2); nsCOMPtr<nsIDocument> doc2 = do_QueryInterface(aNode2);
@ -384,10 +386,12 @@ nsContentUtils::CheckSameOrigin(nsIDOMNode* aNode1, nsIDOMNode* aNode2)
nsCOMPtr<nsIDOMDocument> domDoc2; nsCOMPtr<nsIDOMDocument> domDoc2;
aNode2->GetOwnerDocument(getter_AddRefs(domDoc2)); aNode2->GetOwnerDocument(getter_AddRefs(domDoc2));
doc2 = do_QueryInterface(domDoc2); if (!domDoc2) {
if (!doc2) { // aNode2 is not part of a document, let any caller access it.
return NS_ERROR_FAILURE; return NS_OK;
} }
doc2 = do_QueryInterface(domDoc2);
NS_ASSERTION(doc2, "QI to nsIDocument failed");
} }
if (doc1 == doc2) if (doc1 == doc2)
@ -400,12 +404,52 @@ nsContentUtils::CheckSameOrigin(nsIDOMNode* aNode1, nsIDOMNode* aNode2)
nsresult rv = NS_OK; nsresult rv = NS_OK;
nsCOMPtr<nsIScriptSecurityManager> securityManager = nsCOMPtr<nsIScriptSecurityManager> securityManager =
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv); do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
return securityManager->CheckSameOriginURI(uri1, uri2); return securityManager->CheckSameOriginURI(uri1, uri2);
} }
// static
PRBool
nsContentUtils::CanCallerAccess(nsIDOMNode *aNode)
{
nsCOMPtr<nsIDocument> doc(do_QueryInterface(aNode));
if (!doc) {
// Make sure that this is a real node.
nsCOMPtr<nsIContent> content(do_QueryInterface(aNode));
if (!content) {
return PR_FALSE;
}
nsCOMPtr<nsIDOMDocument> domDoc;
aNode->GetOwnerDocument(getter_AddRefs(domDoc));
if (!domDoc) {
// aNode is not part of a document, let any caller access it.
return PR_TRUE;
}
doc = do_QueryInterface(domDoc);
NS_ASSERTION(doc, "QI to nsIDocument failed");
}
nsCOMPtr<nsIURI> uri;
doc->GetDocumentURL(getter_AddRefs(uri));
nsresult rv = NS_OK;
nsCOMPtr<nsIScriptSecurityManager> securityManager =
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
// If we can't get the security manager service we'll assume that's
// because it's not installed, if that's the case then the installer
// didn't care about security in the first place.
NS_ENSURE_SUCCESS(rv, PR_TRUE);
rv = securityManager->CheckSameOrigin(nsnull, uri);
return NS_SUCCEEDED(rv);
}
// static // static
nsresult nsresult
nsContentUtils::doReparentContentWrapper(nsIContent *aChild, nsContentUtils::doReparentContentWrapper(nsIContent *aChild,
@ -583,34 +627,18 @@ nsContentUtils::ReparentContentWrapper(nsIContent *aContent,
PRBool PRBool
nsContentUtils::IsCallerChrome() nsContentUtils::IsCallerChrome()
{ {
nsCOMPtr<nsIDocShell> docShell; nsresult rv = NS_OK;
nsCOMPtr<nsIThreadJSContextStack> stack(do_GetService(sJSStackContractID)); nsCOMPtr<nsIScriptSecurityManager> securityManager =
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
if (stack) { PRBool is_caller_chrome = PR_FALSE;
JSContext *cx = nsnull; rv = securityManager->SubjectPrincipalIsSystem(&is_caller_chrome);
stack->Peek(&cx); if (NS_FAILED(rv)) {
return PR_FALSE;
if (cx) {
nsCOMPtr<nsIScriptGlobalObject> sgo;
nsContentUtils::GetDynamicScriptGlobal(cx, getter_AddRefs(sgo));
if (sgo) {
sgo->GetDocShell(getter_AddRefs(docShell));
}
}
} }
nsCOMPtr<nsIDocShellTreeItem> item(do_QueryInterface(docShell)); return is_caller_chrome;
if (item) {
PRInt32 callerType = nsIDocShellTreeItem::typeChrome;
item->GetItemType(&callerType);
if (callerType != nsIDocShellTreeItem::typeChrome) {
return PR_FALSE;
}
}
return PR_TRUE;
} }
// static // static

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

@ -125,6 +125,12 @@ nsDOMAttributeMap::SetNamedItem(nsIDOMNode *aNode, nsIDOMNode **aReturn)
*aReturn = nsnull; *aReturn = nsnull;
if (mContent) { if (mContent) {
nsCOMPtr<nsIDOMNode> contNode = do_QueryInterface(mContent);
rv = nsContentUtils::CheckSameOrigin(contNode, aNode);
if (NS_FAILED(rv)) {
return rv;
}
nsCOMPtr<nsIDOMAttr> attribute(do_QueryInterface(aNode)); nsCOMPtr<nsIDOMAttr> attribute(do_QueryInterface(aNode));
if (!attribute) { if (!attribute) {
@ -335,6 +341,12 @@ nsDOMAttributeMap::SetNamedItemNS(nsIDOMNode* aArg, nsIDOMNode** aReturn)
*aReturn = nsnull; *aReturn = nsnull;
if (mContent) { if (mContent) {
nsCOMPtr<nsIDOMNode> contNode = do_QueryInterface(mContent);
rv = nsContentUtils::CheckSameOrigin(contNode, aArg);
if (NS_FAILED(rv)) {
return rv;
}
nsCOMPtr<nsIDOMAttr> attribute(do_QueryInterface(aArg)); nsCOMPtr<nsIDOMAttr> attribute(do_QueryInterface(aArg));
if (!attribute) { if (!attribute) {

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

@ -372,6 +372,14 @@ nsDOMImplementation::CreateDocument(const nsAString& aNamespaceURI,
NS_ENSURE_ARG_POINTER(aReturn); NS_ENSURE_ARG_POINTER(aReturn);
*aReturn = nsnull; *aReturn = nsnull;
if (aDoctype) {
nsCOMPtr<nsIDOMDocument> owner;
aDoctype->GetOwnerDocument(getter_AddRefs(owner));
if (owner) {
return NS_ERROR_DOM_WRONG_DOCUMENT_ERR;
}
}
return NS_NewDOMDocument(aReturn, aNamespaceURI, aQualifiedName, aDoctype, return NS_NewDOMDocument(aReturn, aNamespaceURI, aQualifiedName, aDoctype,
mBaseURI); mBaseURI);
@ -2541,6 +2549,11 @@ nsDocument::ImportNode(nsIDOMNode* aImportedNode,
{ {
NS_ENSURE_ARG(aImportedNode); NS_ENSURE_ARG(aImportedNode);
NS_ENSURE_ARG_POINTER(aReturn); NS_ENSURE_ARG_POINTER(aReturn);
nsresult rv = nsContentUtils::CheckSameOrigin(this, aImportedNode);
if (NS_FAILED(rv)) {
return rv;
}
return aImportedNode->CloneNode(aDeep, aReturn); return aImportedNode->CloneNode(aDeep, aReturn);
} }
@ -2548,6 +2561,11 @@ nsDocument::ImportNode(nsIDOMNode* aImportedNode,
NS_IMETHODIMP NS_IMETHODIMP
nsDocument::AddBinding(nsIDOMElement* aContent, const nsAString& aURL) nsDocument::AddBinding(nsIDOMElement* aContent, const nsAString& aURL)
{ {
nsresult rv = nsContentUtils::CheckSameOrigin(this, aContent);
if (NS_FAILED(rv)) {
return rv;
}
nsCOMPtr<nsIBindingManager> bm; nsCOMPtr<nsIBindingManager> bm;
GetBindingManager(getter_AddRefs(bm)); GetBindingManager(getter_AddRefs(bm));
nsCOMPtr<nsIContent> content(do_QueryInterface(aContent)); nsCOMPtr<nsIContent> content(do_QueryInterface(aContent));
@ -2558,6 +2576,11 @@ nsDocument::AddBinding(nsIDOMElement* aContent, const nsAString& aURL)
NS_IMETHODIMP NS_IMETHODIMP
nsDocument::RemoveBinding(nsIDOMElement* aContent, const nsAString& aURL) nsDocument::RemoveBinding(nsIDOMElement* aContent, const nsAString& aURL)
{ {
nsresult rv = nsContentUtils::CheckSameOrigin(this, aContent);
if (NS_FAILED(rv)) {
return rv;
}
if (mBindingManager) { if (mBindingManager) {
nsCOMPtr<nsIContent> content(do_QueryInterface(aContent)); nsCOMPtr<nsIContent> content(do_QueryInterface(aContent));
return mBindingManager->RemoveLayeredBinding(content, aURL); return mBindingManager->RemoveLayeredBinding(content, aURL);
@ -3148,6 +3171,11 @@ nsDocument::InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild,
return NS_ERROR_NULL_POINTER; return NS_ERROR_NULL_POINTER;
} }
nsresult rv = nsContentUtils::CheckSameOrigin(this, aNewChild);
if (NS_FAILED(rv)) {
return rv;
}
// If it's a child type we can't handle (per DOM spec), or if it's an // If it's a child type we can't handle (per DOM spec), or if it's an
// element and we already have a root (our addition to DOM spec), throw // element and we already have a root (our addition to DOM spec), throw
// HIERARCHY_REQUEST_ERR. // HIERARCHY_REQUEST_ERR.
@ -3217,6 +3245,11 @@ nsDocument::ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild, nsIDOMNod
return NS_ERROR_NULL_POINTER; return NS_ERROR_NULL_POINTER;
} }
result = nsContentUtils::CheckSameOrigin(this, aNewChild);
if (NS_FAILED(result)) {
return result;
}
aNewChild->GetNodeType(&nodeType); aNewChild->GetNodeType(&nodeType);
if ((COMMENT_NODE != nodeType) && if ((COMMENT_NODE != nodeType) &&

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

@ -2334,6 +2334,12 @@ nsGenericElement::doInsertBefore(nsIDOMNode* aNewChild,
return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR; return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
} }
nsCOMPtr<nsIDocument> old_doc;
newContent->GetDocument(*getter_AddRefs(old_doc));
if (old_doc != mDocument && !nsContentUtils::CanCallerAccess(aNewChild)) {
return NS_ERROR_DOM_SECURITY_ERR;
}
/* /*
* Make sure the new child is not "this" node or one of this nodes * Make sure the new child is not "this" node or one of this nodes
* ancestors. Doing this check here should be safe even if newContent * ancestors. Doing this check here should be safe even if newContent
@ -2410,10 +2416,6 @@ nsGenericElement::doInsertBefore(nsIDOMNode* aNewChild,
return res; return res;
} }
nsCOMPtr<nsIDocument> old_doc;
newContent->GetDocument(*getter_AddRefs(old_doc));
/* /*
* Remove the element from the old parent if one exists, since oldParent * Remove the element from the old parent if one exists, since oldParent
* is a nsIDOMNode this will do the right thing even if the parent of * is a nsIDOMNode this will do the right thing even if the parent of
@ -2548,6 +2550,12 @@ nsGenericElement::doReplaceChild(nsIDOMNode* aNewChild,
return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR; return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
} }
nsCOMPtr<nsIDocument> old_doc;
newContent->GetDocument(*getter_AddRefs(old_doc));
if (old_doc != mDocument && !nsContentUtils::CanCallerAccess(aNewChild)) {
return NS_ERROR_DOM_SECURITY_ERR;
}
nsCOMPtr<nsIDocument> document; nsCOMPtr<nsIDocument> document;
GetDocument(*getter_AddRefs(document)); GetDocument(*getter_AddRefs(document));
@ -2610,10 +2618,6 @@ nsGenericElement::doReplaceChild(nsIDOMNode* aNewChild,
return res; return res;
} }
nsCOMPtr<nsIDocument> old_doc;
newContent->GetDocument(*getter_AddRefs(old_doc));
/* /*
* Remove the element from the old parent if one exists, since oldParent * Remove the element from the old parent if one exists, since oldParent
* is a nsIDOMNode this will do the right thing even if the parent of * is a nsIDOMNode this will do the right thing even if the parent of

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

@ -985,6 +985,11 @@ nsresult nsRange::GetCommonAncestorContainer(nsIDOMNode** aCommonParent)
nsresult nsRange::SetStart(nsIDOMNode* aParent, PRInt32 aOffset) nsresult nsRange::SetStart(nsIDOMNode* aParent, PRInt32 aOffset)
{ {
NS_ENSURE_ARG_POINTER(aParent); NS_ENSURE_ARG_POINTER(aParent);
if (!nsContentUtils::CanCallerAccess(aParent)) {
return NS_ERROR_DOM_SECURITY_ERR;
}
if(IsDetached()) if(IsDetached())
return NS_ERROR_DOM_INVALID_STATE_ERR; return NS_ERROR_DOM_INVALID_STATE_ERR;
@ -1009,6 +1014,10 @@ nsresult nsRange::SetStart(nsIDOMNode* aParent, PRInt32 aOffset)
nsresult nsRange::SetStartBefore(nsIDOMNode* aSibling) nsresult nsRange::SetStartBefore(nsIDOMNode* aSibling)
{ {
if (!nsContentUtils::CanCallerAccess(aSibling)) {
return NS_ERROR_DOM_SECURITY_ERR;
}
if(IsDetached()) if(IsDetached())
return NS_ERROR_DOM_INVALID_STATE_ERR; return NS_ERROR_DOM_INVALID_STATE_ERR;
if (nsnull == aSibling)// Not the correct one to throw, but spec doesn't say what is if (nsnull == aSibling)// Not the correct one to throw, but spec doesn't say what is
@ -1023,6 +1032,10 @@ nsresult nsRange::SetStartBefore(nsIDOMNode* aSibling)
nsresult nsRange::SetStartAfter(nsIDOMNode* aSibling) nsresult nsRange::SetStartAfter(nsIDOMNode* aSibling)
{ {
if (!nsContentUtils::CanCallerAccess(aSibling)) {
return NS_ERROR_DOM_SECURITY_ERR;
}
if(IsDetached()) if(IsDetached())
return NS_ERROR_DOM_INVALID_STATE_ERR; return NS_ERROR_DOM_INVALID_STATE_ERR;
if (nsnull == aSibling)// Not the correct one to throw, but spec doesn't say what is if (nsnull == aSibling)// Not the correct one to throw, but spec doesn't say what is
@ -1037,6 +1050,10 @@ nsresult nsRange::SetStartAfter(nsIDOMNode* aSibling)
nsresult nsRange::SetEnd(nsIDOMNode* aParent, PRInt32 aOffset) nsresult nsRange::SetEnd(nsIDOMNode* aParent, PRInt32 aOffset)
{ {
if (!nsContentUtils::CanCallerAccess(aParent)) {
return NS_ERROR_DOM_SECURITY_ERR;
}
if(IsDetached()) if(IsDetached())
return NS_ERROR_DOM_INVALID_STATE_ERR; return NS_ERROR_DOM_INVALID_STATE_ERR;
@ -1065,6 +1082,10 @@ nsresult nsRange::SetEnd(nsIDOMNode* aParent, PRInt32 aOffset)
nsresult nsRange::SetEndBefore(nsIDOMNode* aSibling) nsresult nsRange::SetEndBefore(nsIDOMNode* aSibling)
{ {
if (!nsContentUtils::CanCallerAccess(aSibling)) {
return NS_ERROR_DOM_SECURITY_ERR;
}
if(IsDetached()) if(IsDetached())
return NS_ERROR_DOM_INVALID_STATE_ERR; return NS_ERROR_DOM_INVALID_STATE_ERR;
if (nsnull == aSibling)// Not the correct one to throw, but spec doesn't say what is if (nsnull == aSibling)// Not the correct one to throw, but spec doesn't say what is
@ -1079,6 +1100,10 @@ nsresult nsRange::SetEndBefore(nsIDOMNode* aSibling)
nsresult nsRange::SetEndAfter(nsIDOMNode* aSibling) nsresult nsRange::SetEndAfter(nsIDOMNode* aSibling)
{ {
if (!nsContentUtils::CanCallerAccess(aSibling)) {
return NS_ERROR_DOM_SECURITY_ERR;
}
if(IsDetached()) if(IsDetached())
return NS_ERROR_DOM_INVALID_STATE_ERR; return NS_ERROR_DOM_INVALID_STATE_ERR;
if (nsnull == aSibling)// Not the correct one to throw, but spec doesn't say what is if (nsnull == aSibling)// Not the correct one to throw, but spec doesn't say what is
@ -1112,6 +1137,10 @@ nsresult nsRange::Unposition()
nsresult nsRange::SelectNode(nsIDOMNode* aN) nsresult nsRange::SelectNode(nsIDOMNode* aN)
{ {
if (!nsContentUtils::CanCallerAccess(aN)) {
return NS_ERROR_DOM_SECURITY_ERR;
}
if(IsDetached()) if(IsDetached())
return NS_ERROR_DOM_INVALID_STATE_ERR; return NS_ERROR_DOM_INVALID_STATE_ERR;
@ -1160,6 +1189,10 @@ nsresult nsRange::SelectNode(nsIDOMNode* aN)
nsresult nsRange::SelectNodeContents(nsIDOMNode* aN) nsresult nsRange::SelectNodeContents(nsIDOMNode* aN)
{ {
if (!nsContentUtils::CanCallerAccess(aN)) {
return NS_ERROR_DOM_SECURITY_ERR;
}
if(IsDetached()) if(IsDetached())
return NS_ERROR_DOM_INVALID_STATE_ERR; return NS_ERROR_DOM_INVALID_STATE_ERR;
NS_ENSURE_ARG_POINTER(aN); NS_ENSURE_ARG_POINTER(aN);
@ -2026,6 +2059,10 @@ nsresult nsRange::CloneRange(nsIDOMRange** aReturn)
nsresult nsRange::InsertNode(nsIDOMNode* aN) nsresult nsRange::InsertNode(nsIDOMNode* aN)
{ {
if (!nsContentUtils::CanCallerAccess(aN)) {
return NS_ERROR_DOM_SECURITY_ERR;
}
if(IsDetached()) if(IsDetached())
return NS_ERROR_DOM_INVALID_STATE_ERR; return NS_ERROR_DOM_INVALID_STATE_ERR;
@ -2078,6 +2115,10 @@ nsresult nsRange::InsertNode(nsIDOMNode* aN)
nsresult nsRange::SurroundContents(nsIDOMNode* aN) nsresult nsRange::SurroundContents(nsIDOMNode* aN)
{ {
if (!nsContentUtils::CanCallerAccess(aN)) {
return NS_ERROR_DOM_SECURITY_ERR;
}
if(IsDetached()) if(IsDetached())
return NS_ERROR_DOM_INVALID_STATE_ERR; return NS_ERROR_DOM_INVALID_STATE_ERR;

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

@ -171,6 +171,8 @@ nsXMLNamedNodeMap::SetNamedItem(nsIDOMNode* aArg, nsIDOMNode** aReturn)
return NS_ERROR_NULL_POINTER; return NS_ERROR_NULL_POINTER;
*aReturn = 0; *aReturn = 0;
// XXX, do same-origin check here once we know what to do with this class
nsAutoString argName; nsAutoString argName;
aArg->GetNodeName(argName); aArg->GetNodeName(argName);

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

@ -987,7 +987,9 @@ nsXULElement::InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild,
// aRefChild may be null; that means "append". // aRefChild may be null; that means "append".
nsresult rv; nsresult rv = nsContentUtils::CheckSameOrigin(this, aNewChild);
if (NS_FAILED(rv))
return rv;
nsCOMPtr<nsIContent> newcontent = do_QueryInterface(aNewChild); nsCOMPtr<nsIContent> newcontent = do_QueryInterface(aNewChild);
NS_ASSERTION(newcontent != nsnull, "not an nsIContent"); NS_ASSERTION(newcontent != nsnull, "not an nsIContent");
@ -1065,7 +1067,9 @@ nsXULElement::ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild,
if (! aOldChild) if (! aOldChild)
return NS_ERROR_NULL_POINTER; return NS_ERROR_NULL_POINTER;
nsresult rv; nsresult rv = nsContentUtils::CheckSameOrigin(this, aNewChild);
if (NS_FAILED(rv))
return rv;
nsCOMPtr<nsIContent> oldelement = do_QueryInterface(aOldChild); nsCOMPtr<nsIContent> oldelement = do_QueryInterface(aOldChild);
NS_ASSERTION(oldelement != nsnull, "not an nsIContent"); NS_ASSERTION(oldelement != nsnull, "not an nsIContent");

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

@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK ***** /* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1 * Version: NPL 1.1/GPL 2.0/LGPL 2.1
* *
@ -68,6 +68,7 @@
#include "nsContentUtils.h" #include "nsContentUtils.h"
#include "nsReadableUtils.h" #include "nsReadableUtils.h"
#include "nsCRT.h" #include "nsCRT.h"
#include "nsDOMError.h"
#ifdef PR_LOGGING #ifdef PR_LOGGING
static PRLogModuleInfo* gLog; static PRLogModuleInfo* gLog;
@ -216,6 +217,10 @@ nsXULCommandDispatcher::AddCommandUpdater(nsIDOMElement* aElement,
if (! aElement) if (! aElement)
return NS_ERROR_NULL_POINTER; return NS_ERROR_NULL_POINTER;
if (!nsContentUtils::CanCallerAccess(aElement)) {
return NS_ERROR_DOM_SECURITY_ERR;
}
Updater* updater = mUpdaters; Updater* updater = mUpdaters;
Updater** link = &mUpdaters; Updater** link = &mUpdaters;

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

@ -1937,6 +1937,11 @@ nsXULDocument::AddBroadcastListenerFor(nsIDOMElement* aBroadcaster,
nsIDOMElement* aListener, nsIDOMElement* aListener,
const nsAString& aAttr) const nsAString& aAttr)
{ {
if (!nsContentUtils::CanCallerAccess(aBroadcaster) ||
!nsContentUtils::CanCallerAccess(aListener)) {
return NS_ERROR_DOM_SECURITY_ERR;
}
static PLDHashTableOps gOps = { static PLDHashTableOps gOps = {
PL_DHashAllocTable, PL_DHashAllocTable,
PL_DHashFreeTable, PL_DHashFreeTable,
@ -3375,6 +3380,11 @@ NS_IMETHODIMP
nsXULDocument::AddBinding(nsIDOMElement* aContent, nsXULDocument::AddBinding(nsIDOMElement* aContent,
const nsAString& aURL) const nsAString& aURL)
{ {
nsresult rv = nsContentUtils::CheckSameOrigin(this, aContent);
if (NS_FAILED(rv)) {
return rv;
}
nsCOMPtr<nsIBindingManager> bm; nsCOMPtr<nsIBindingManager> bm;
GetBindingManager(getter_AddRefs(bm)); GetBindingManager(getter_AddRefs(bm));
nsCOMPtr<nsIContent> content(do_QueryInterface(aContent)); nsCOMPtr<nsIContent> content(do_QueryInterface(aContent));

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

@ -33,6 +33,7 @@ REQUIRES = xpcom \
htmlparser \ htmlparser \
webshell \ webshell \
docshell \ docshell \
caps \
$(NULL) $(NULL)
include <$(DEPTH)/config/config.mak> include <$(DEPTH)/config/config.mak>

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

@ -35,6 +35,9 @@ REQUIRES = string \
content \ content \
widget \ widget \
necko \ necko \
caps \
xpconnect \
js \
$(NULL) $(NULL)
endif endif

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

@ -28,6 +28,9 @@ REQUIRES = string \
content \ content \
widget \ widget \
necko \ necko \
caps \
xpconnect \
js \
$(NULL) $(NULL)
include <$(DEPTH)/config/config.mak> include <$(DEPTH)/config/config.mak>

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

@ -34,6 +34,10 @@
#ifndef TX_EXE #ifndef TX_EXE
#include "nsNetUtil.h" #include "nsNetUtil.h"
#include "nsIScriptSecurityManager.h"
#include "nsIDocument.h"
#include "nsIDOMDocument.h"
#include "nsIContent.h"
#endif #endif
/** /**
@ -311,4 +315,46 @@ URIUtils::ParsedURI* URIUtils::parseURI(const String& uri) {
return uriTokens; return uriTokens;
} //-- parseURI } //-- parseURI
#endif #else /* TX_EXE */
// static
MBool URIUtils::CanCallerAccess(nsIDOMNode *aNode)
{
nsCOMPtr<nsIDocument> doc(do_QueryInterface(aNode));
if (!doc) {
// Make sure that this is a real node.
nsCOMPtr<nsIContent> content(do_QueryInterface(aNode));
if (!content) {
return MB_FALSE;
}
nsCOMPtr<nsIDOMDocument> domDoc;
aNode->GetOwnerDocument(getter_AddRefs(domDoc));
if (!domDoc) {
// aNode is not part of a document, let any caller access it.
return PR_TRUE;
}
doc = do_QueryInterface(domDoc);
NS_ASSERTION(doc, "QI to nsIDocument failed");
}
nsCOMPtr<nsIURI> uri;
doc->GetDocumentURL(getter_AddRefs(uri));
nsresult rv = NS_OK;
nsCOMPtr<nsIScriptSecurityManager> securityManager =
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
// If we can't get the security manager service we'll assume that's
// because it's not installed, if that's the case then the installer
// didn't care about security in the first place.
NS_ENSURE_SUCCESS(rv, PR_TRUE);
rv = securityManager->CheckSameOrigin(nsnull, uri);
return NS_SUCCEEDED(rv);
}
#endif /* TX_EXE */

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

@ -40,6 +40,8 @@
#include "baseutils.h" #include "baseutils.h"
#ifdef TX_EXE #ifdef TX_EXE
#include <fstream.h> #include <fstream.h>
#else
#include "nsIDOMNode.h"
#endif #endif
@ -86,7 +88,15 @@ public:
* The document base will be appended to the given dest String * The document base will be appended to the given dest String
**/ **/
static void getDocumentBase(const String& href, String& dest); static void getDocumentBase(const String& href, String& dest);
#endif
#else /* TX_EXE */
/*
* Checks if a caller is allowed to access a given node
*/
static MBool CanCallerAccess(nsIDOMNode *aNode);
#endif /* TX_EXE */
/** /**
* Resolves the given href argument, using the given documentBase * Resolves the given href argument, using the given documentBase

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

@ -47,6 +47,9 @@
#include "ProcessorState.h" #include "ProcessorState.h"
#include "nsContentCID.h" #include "nsContentCID.h"
#include "ExprParser.h" #include "ExprParser.h"
#include "nsDOMError.h"
#include "txURIUtils.h"
NS_IMPL_ADDREF(nsXPathEvaluator) NS_IMPL_ADDREF(nsXPathEvaluator)
NS_IMPL_RELEASE(nsXPathEvaluator) NS_IMPL_RELEASE(nsXPathEvaluator)
@ -91,6 +94,9 @@ nsXPathEvaluator::CreateNSResolver(nsIDOMNode *aNodeResolver,
nsIDOMXPathNSResolver **aResult) nsIDOMXPathNSResolver **aResult)
{ {
NS_ENSURE_ARG(aNodeResolver); NS_ENSURE_ARG(aNodeResolver);
if (!URIUtils::CanCallerAccess(aNodeResolver))
return NS_ERROR_DOM_SECURITY_ERR;
*aResult = new nsXPathNSResolver(aNodeResolver); *aResult = new nsXPathNSResolver(aNodeResolver);
NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY); NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);

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

@ -43,6 +43,9 @@
#include "nsIDOMClassInfo.h" #include "nsIDOMClassInfo.h"
#include "nsIDOMXPathNamespace.h" #include "nsIDOMXPathNamespace.h"
#include "nsXPathResult.h" #include "nsXPathResult.h"
#include "nsDOMError.h"
#include "txURIUtils.h"
NS_IMPL_ADDREF(nsXPathExpression) NS_IMPL_ADDREF(nsXPathExpression)
NS_IMPL_RELEASE(nsXPathExpression) NS_IMPL_RELEASE(nsXPathExpression)
@ -70,6 +73,9 @@ nsXPathExpression::Evaluate(nsIDOMNode *aContextNode,
{ {
NS_ENSURE_ARG(aContextNode); NS_ENSURE_ARG(aContextNode);
if (!URIUtils::CanCallerAccess(aContextNode))
return NS_ERROR_DOM_SECURITY_ERR;
nsresult rv; nsresult rv;
PRUint16 nodeType; PRUint16 nodeType;
rv = aContextNode->GetNodeType(&nodeType); rv = aContextNode->GetNodeType(&nodeType);

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

@ -67,6 +67,7 @@
#include "nsNetUtil.h" #include "nsNetUtil.h"
#include "nsIDOMClassInfo.h" #include "nsIDOMClassInfo.h"
#include "nsIConsoleService.h" #include "nsIConsoleService.h"
#include "nsDOMError.h"
#else #else
#include "txHTMLOutput.h" #include "txHTMLOutput.h"
#include "txTextOutput.h" #include "txTextOutput.h"
@ -2329,9 +2330,14 @@ XSLTProcessor::TransformDocument(nsIDOMNode* aSourceDOM,
nsIDOMDocument* aOutputDoc, nsIDOMDocument* aOutputDoc,
nsITransformObserver* aObserver) nsITransformObserver* aObserver)
{ {
// We need source and result documents but no stylesheet.
NS_ENSURE_ARG(aSourceDOM); NS_ENSURE_ARG(aSourceDOM);
NS_ENSURE_ARG(aStyleDOM);
NS_ENSURE_ARG(aOutputDoc); NS_ENSURE_ARG(aOutputDoc);
if (!URIUtils::CanCallerAccess(aSourceDOM) ||
!URIUtils::CanCallerAccess(aStyleDOM) ||
!URIUtils::CanCallerAccess(aOutputDoc))
return NS_ERROR_DOM_SECURITY_ERR;
// Create wrapper for the source document. // Create wrapper for the source document.
nsCOMPtr<nsIDOMDocument> sourceDOMDocument; nsCOMPtr<nsIDOMDocument> sourceDOMDocument;