Reenable same-origin checks. Patch by me and jst.

b=156452 r=peterv/sicking/jst sr=bz/jst a=chofmann
This commit is contained in:
sicking%bigfoot.com 2002-07-18 05:53:28 +00:00
Родитель 47a7058762
Коммит bde13bef02
10 изменённых файлов: 230 добавлений и 139 удалений

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

@ -47,6 +47,7 @@ class nsIScriptGlobalObject;
class nsIXPConnect;
class nsIContent;
class nsIDocument;
class nsIScriptSecurityManager;
class nsContentUtils
@ -167,8 +168,15 @@ public:
static void Shutdown();
// Checks if two nodes live in document coming from the same origin
static nsresult CheckSameOrigin(nsIDOMNode* aNode1, nsIDOMNode* aNode2);
/**
* Checks whether two nodes come from the same origin. aTrustedNode is
* considered 'safe' in that a user can operate on it and that it isn't
* a js-object that implements nsIDOMNode.
* Never call this function with the first node provided by script, it
* must always be known to be a 'real' node!
*/
static nsresult CheckSameOrigin(nsIDOMNode* aTrustedNode,
nsIDOMNode* aUnTrustedNode);
// Check if the (JS) caller can access aNode.
static PRBool CanCallerAccess(nsIDOMNode *aNode);
@ -184,6 +192,8 @@ private:
static nsIDOMScriptObjectFactory *sDOMScriptObjectFactory;
static nsIXPConnect *sXPConnect;
static nsIScriptSecurityManager *sSecurityManager;
};
#define NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(_class) \

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

@ -62,6 +62,7 @@ static const char *sJSStackContractID = "@mozilla.org/js/xpc/ContextStack;1";
nsIDOMScriptObjectFactory *nsContentUtils::sDOMScriptObjectFactory = nsnull;
nsIXPConnect *nsContentUtils::sXPConnect = nsnull;
nsIScriptSecurityManager *nsContentUtils::sSecurityManager = nsnull;
// static
nsresult
@ -74,6 +75,13 @@ nsContentUtils::Init()
(nsISupports **)&sXPConnect);
NS_ENSURE_SUCCESS(rv, rv);
rv = nsServiceManager::GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID,
nsIScriptSecurityManager::GetIID(),
(nsISupports **)&sSecurityManager);
if (NS_FAILED(rv)) {
sSecurityManager = nsnull;
}
return rv;
}
@ -232,7 +240,8 @@ class CopyNormalizeNewlines
typedef typename OutputIterator::value_type value_type;
public:
CopyNormalizeNewlines(OutputIterator* aDestination,PRBool aLastCharCR=PR_FALSE) :
CopyNormalizeNewlines(OutputIterator* aDestination,
PRBool aLastCharCR=PR_FALSE) :
mLastCharCR(aLastCharCR),
mDestination(aDestination),
mWritten(0)
@ -332,6 +341,7 @@ nsContentUtils::Shutdown()
{
NS_IF_RELEASE(sDOMScriptObjectFactory);
NS_IF_RELEASE(sXPConnect);
NS_IF_RELEASE(sSecurityManager);
}
// static
@ -354,43 +364,72 @@ nsContentUtils::GetClassInfoInstance(nsDOMClassInfoID aID)
return sDOMScriptObjectFactory->GetClassInfoInstance(aID);
}
/**
* Checks whether two nodes come from the same origin. aTrustedNode is
* considered 'safe' in that a user can operate on it and that it isn't
* a js-object that implements nsIDOMNode.
* Never call this function with the first node provided by script, it
* must always be known to be a 'real' node!
*/
// static
nsresult
nsContentUtils::CheckSameOrigin(nsIDOMNode *aNode1, nsIDOMNode *aNode2)
nsContentUtils::CheckSameOrigin(nsIDOMNode *aTrustedNode,
nsIDOMNode *aUnTrustedNode)
{
nsCOMPtr<nsIDocument> doc1 = do_QueryInterface(aNode1);
if (!doc1) {
// Make sure that this is a real node.
nsCOMPtr<nsIContent> cont1 = do_QueryInterface(aNode1);
if (!cont1) {
return NS_ERROR_DOM_SECURITY_ERR;
}
NS_PRECONDITION(aTrustedNode, "There must be a trusted node");
// In most cases this is a document, so lets try that first
nsCOMPtr<nsIDocument> doc1 = do_QueryInterface(aTrustedNode);
nsCOMPtr<nsIDOMDocument> domDoc1;
aNode1->GetOwnerDocument(getter_AddRefs(domDoc1));
if (!domDoc1) {
// aNode1 is not part of a document, let any caller access it.
return NS_OK;
if (!doc1) {
#ifdef DEBUG
nsCOMPtr<nsIContent> trustCont = do_QueryInterface(aTrustedNode);
NS_ASSERTION(trustCont,
"aTrustedNode is neither nsIContent nor nsIDocument!");
#endif
nsCOMPtr<nsIDOMDocument> domDoc;
aTrustedNode->GetOwnerDocument(getter_AddRefs(domDoc));
if (!domDoc) {
// aTrustedNode isn't part of a document so we can't check security
// against it.
return NS_ERROR_UNEXPECTED;
}
doc1 = do_QueryInterface(domDoc1);
doc1 = do_QueryInterface(domDoc);
NS_ASSERTION(doc1, "QI to nsIDocument failed");
}
nsCOMPtr<nsIDocument> doc2 = do_QueryInterface(aNode2);
// For performance reasons it's important to try to QI the node to
// nsIContent before trying to QI to nsIDocument since a QI miss on
// a node is potentially expensive.
nsCOMPtr<nsIContent> content = do_QueryInterface(aUnTrustedNode);
nsCOMPtr<nsIDocument> doc2;
if (!content) {
doc2 = do_QueryInterface(aUnTrustedNode);
if (!doc2) {
// Make sure that this is a real node.
nsCOMPtr<nsIContent> cont2 = do_QueryInterface(aNode2);
if (!cont2) {
return NS_ERROR_DOM_SECURITY_ERR;
// aUnTrustedNode is neither a nsIContent nor an nsIDocument, something
// weird is going on...
NS_ERROR("aUnTrustedNode is neither an nsIContent nor an nsIDocument!");
return NS_ERROR_UNEXPECTED;
}
}
nsCOMPtr<nsIDOMDocument> domDoc2;
aNode2->GetOwnerDocument(getter_AddRefs(domDoc2));
if (!domDoc2) {
// aNode2 is not part of a document, let any caller access it.
if (!doc2) {
nsCOMPtr<nsIDOMDocument> domDoc;
aUnTrustedNode->GetOwnerDocument(getter_AddRefs(domDoc));
if (!domDoc) {
// aUnTrustedNode is not part of a document, let any caller access it.
return NS_OK;
}
doc2 = do_QueryInterface(domDoc2);
doc2 = do_QueryInterface(domDoc);
NS_ASSERTION(doc2, "QI to nsIDocument failed");
}
@ -402,54 +441,69 @@ nsContentUtils::CheckSameOrigin(nsIDOMNode *aNode1, nsIDOMNode *aNode2)
nsCOMPtr<nsIURI> uri2;
doc2->GetDocumentURL(getter_AddRefs(uri2));
nsresult rv = NS_OK;
nsCOMPtr<nsIScriptSecurityManager> securityManager =
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
// The untrusted node doesn't have a uri so we'll allow it to be accessed.
if (!uri2) {
return NS_OK;
}
return securityManager->CheckSameOriginURI(uri1, uri2);
// If there isn't a security manager it is probably because it is not
// installed so we don't care about security anyway
if (!sSecurityManager) {
return NS_OK;
}
return sSecurityManager->CheckSameOriginURI(uri1, uri2);
}
// static
PRBool
nsContentUtils::CanCallerAccess(nsIDOMNode *aNode)
{
// DISABLED UNTIL THE SLOWDOWN IN TXUL, TP AND TS GETS RESOLVED
// (SEE BUG 156452).
return PR_TRUE;
// Make sure that this is a real node. We do this by first QI'ing to
// nsIContent (which is important performance wise) and if that QI
// fails we QI to nsIDocument. If both those QI's fail we won't let
// the caller access this unknown node.
nsCOMPtr<nsIDocument> doc(do_QueryInterface(aNode));
nsCOMPtr<nsIContent> content(do_QueryInterface(aNode));
nsCOMPtr<nsIDocument> doc;
if (!content) {
doc = do_QueryInterface(aNode);
if (!doc) {
// Make sure that this is a real node.
nsCOMPtr<nsIContent> content(do_QueryInterface(aNode));
if (!content) {
// aNode is neither a nsIContent nor an nsIDocument, something
// weird is going on...
NS_ERROR("aNode is neither an nsIContent nor an nsIDocument!");
return PR_FALSE;
}
}
if (!doc) {
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");
}
if (!sSecurityManager) {
// No security manager available, let any calls go through...
return PR_TRUE;
}
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);
nsresult rv = sSecurityManager->CheckSameOrigin(nsnull, uri);
return NS_SUCCEEDED(rv);
}
@ -631,13 +685,12 @@ nsContentUtils::ReparentContentWrapper(nsIContent *aContent,
PRBool
nsContentUtils::IsCallerChrome()
{
nsresult rv = NS_OK;
nsCOMPtr<nsIScriptSecurityManager> securityManager =
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
if (!sSecurityManager) {
return NS_OK;
}
PRBool is_caller_chrome = PR_FALSE;
rv = securityManager->SubjectPrincipalIsSystem(&is_caller_chrome);
nsresult rv = sSecurityManager->SubjectPrincipalIsSystem(&is_caller_chrome);
if (NS_FAILED(rv)) {
return PR_FALSE;
}

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

@ -125,11 +125,8 @@ nsDOMAttributeMap::SetNamedItem(nsIDOMNode *aNode, nsIDOMNode **aReturn)
*aReturn = nsnull;
if (mContent) {
nsCOMPtr<nsIDOMNode> contNode = do_QueryInterface(mContent);
rv = nsContentUtils::CheckSameOrigin(contNode, aNode);
if (NS_FAILED(rv)) {
return rv;
}
// XXX should check same-origin between mContent and aNode however
// nsContentUtils::CheckSameOrigin can't deal with attributenodes yet
nsCOMPtr<nsIDOMAttr> attribute(do_QueryInterface(aNode));
@ -341,11 +338,8 @@ nsDOMAttributeMap::SetNamedItemNS(nsIDOMNode* aArg, nsIDOMNode** aReturn)
*aReturn = nsnull;
if (mContent) {
nsCOMPtr<nsIDOMNode> contNode = do_QueryInterface(mContent);
rv = nsContentUtils::CheckSameOrigin(contNode, aArg);
if (NS_FAILED(rv)) {
return rv;
}
// XXX should check same-origin between mContent and aNode however
// nsContentUtils::CheckSameOrigin can't deal with attributenodes yet
nsCOMPtr<nsIDOMAttr> attribute(do_QueryInterface(aArg));

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

@ -2336,7 +2336,8 @@ nsGenericElement::doInsertBefore(nsIDOMNode* aNewChild,
nsCOMPtr<nsIDocument> old_doc;
newContent->GetDocument(*getter_AddRefs(old_doc));
if (old_doc != mDocument && !nsContentUtils::CanCallerAccess(aNewChild)) {
if (old_doc && old_doc != mDocument &&
!nsContentUtils::CanCallerAccess(aNewChild)) {
return NS_ERROR_DOM_SECURITY_ERR;
}
@ -2552,7 +2553,8 @@ nsGenericElement::doReplaceChild(nsIDOMNode* aNewChild,
nsCOMPtr<nsIDocument> old_doc;
newContent->GetDocument(*getter_AddRefs(old_doc));
if (old_doc != mDocument && !nsContentUtils::CanCallerAccess(aNewChild)) {
if (old_doc && old_doc != mDocument &&
!nsContentUtils::CanCallerAccess(aNewChild)) {
return NS_ERROR_DOM_SECURITY_ERR;
}

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

@ -924,8 +924,9 @@ nsXULElement::GetOwnerDocument(nsIDOMDocument** aOwnerDocument)
return mDocument->QueryInterface(NS_GET_IID(nsIDOMDocument), (void**) aOwnerDocument);
}
else {
*aOwnerDocument = nsnull;
return NS_OK;
nsCOMPtr<nsIDocument> doc;
NodeInfo()->GetDocument(*getter_AddRefs(doc));
return CallQueryInterface(doc, aOwnerDocument);
}
}

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

@ -217,8 +217,12 @@ nsXULCommandDispatcher::AddCommandUpdater(nsIDOMElement* aElement,
if (! aElement)
return NS_ERROR_NULL_POINTER;
if (!nsContentUtils::CanCallerAccess(aElement)) {
return NS_ERROR_DOM_SECURITY_ERR;
nsCOMPtr<nsIDOMNode> doc(do_QueryInterface(mDocument));
nsresult rv = nsContentUtils::CheckSameOrigin(doc, aElement);
if (NS_FAILED(rv)) {
return rv;
}
Updater* updater = mUpdaters;

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

@ -1937,9 +1937,16 @@ nsXULDocument::AddBroadcastListenerFor(nsIDOMElement* aBroadcaster,
nsIDOMElement* aListener,
const nsAString& aAttr)
{
if (!nsContentUtils::CanCallerAccess(aBroadcaster) ||
!nsContentUtils::CanCallerAccess(aListener)) {
return NS_ERROR_DOM_SECURITY_ERR;
nsresult rv = nsContentUtils::CheckSameOrigin(this, aBroadcaster);
if (NS_FAILED(rv)) {
return rv;
}
rv = nsContentUtils::CheckSameOrigin(this, aListener);
if (NS_FAILED(rv)) {
return rv;
}
static PLDHashTableOps gOps = {

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

@ -40,6 +40,8 @@
#include "XSLTProcessor.h"
#include "TxLog.h"
#include "nsCRT.h"
#include "nsIScriptSecurityManager.h"
#include "txURIUtils.h"
/* 1c1a3c01-14f6-11d6-a7f2-ea502af815dc */
#define TRANSFORMIIX_DOMCI_EXTENSION_CID \
@ -169,6 +171,7 @@ PR_STATIC_CALLBACK(nsresult)
Initialize(nsIModule* aSelf)
{
NS_PRECONDITION(!gInitialized, "module already initialized");
nsresult rv = NS_OK;
if (gInitialized)
return NS_OK;
@ -192,7 +195,15 @@ Initialize(nsIModule* aSelf)
return NS_ERROR_OUT_OF_MEMORY;
if (!txHTMLAtoms::init())
return NS_ERROR_OUT_OF_MEMORY;
rv = CallGetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &gTxSecurityManager);
if (NS_FAILED(rv)) {
gTxSecurityManager = nsnull;
return rv;
}
TX_LG_CREATE;
return NS_OK;
}
@ -225,6 +236,9 @@ Shutdown(nsIModule* aSelf)
txXPathAtoms::shutdown();
txXSLTAtoms::shutdown();
txHTMLAtoms::shutdown();
NS_IF_RELEASE(gTxSecurityManager);
TX_LG_DELETE;
}

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

@ -317,22 +317,31 @@ URIUtils::ParsedURI* URIUtils::parseURI(const String& uri) {
#else /* TX_EXE */
nsIScriptSecurityManager *gTxSecurityManager = 0;
// static
MBool URIUtils::CanCallerAccess(nsIDOMNode *aNode)
PRBool URIUtils::CanCallerAccess(nsIDOMNode *aNode)
{
// DISABLED UNTIL THE SLOWDOWN IN TXUL, TP AND TS GETS RESOLVED
// (SEE BUG 156452).
return PR_TRUE;
// Make sure that this is a real node. We do this by first QI'ing to
// nsIContent (which is important performance wise) and if that QI
// fails we QI to nsIDocument. If both those QI's fail we won't let
// the caller access this unknown node.
nsCOMPtr<nsIDocument> doc(do_QueryInterface(aNode));
nsCOMPtr<nsIDocument> doc;
if (!doc) {
// Make sure that this is a real node.
nsCOMPtr<nsIContent> content(do_QueryInterface(aNode));
if (!content) {
return MB_FALSE;
doc = do_QueryInterface(aNode);
if (!doc) {
// aNode is neither a nsIContent nor an nsIDocument, something
// weird is going on...
return PR_FALSE;
}
}
if (!doc) {
nsCOMPtr<nsIDOMDocument> domDoc;
aNode->GetOwnerDocument(getter_AddRefs(domDoc));
if (!domDoc) {
@ -343,21 +352,15 @@ MBool URIUtils::CanCallerAccess(nsIDOMNode *aNode)
NS_ASSERTION(doc, "QI to nsIDocument failed");
}
if (!gTxSecurityManager) {
// No security manager available, let any calls go through...
return PR_TRUE;
}
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);
return NS_SUCCEEDED(gTxSecurityManager->CheckSameOrigin(nsnull, uri));
}

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

@ -42,8 +42,11 @@
#include <fstream.h>
#else
#include "nsIDOMNode.h"
#endif
class nsIScriptSecurityManager;
extern nsIScriptSecurityManager *gTxSecurityManager;
#endif
/**
* A utility class for URI handling
@ -94,7 +97,7 @@ public:
/*
* Checks if a caller is allowed to access a given node
*/
static MBool CanCallerAccess(nsIDOMNode *aNode);
static PRBool CanCallerAccess(nsIDOMNode *aNode);
#endif /* TX_EXE */