Use principals instead of URIs for same-origin checks.
b=159348, r=bz, sr=jst, a=asa git-svn-id: svn://10.0.0.236/trunk@126081 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -218,6 +218,13 @@ interface nsIScriptSecurityManager : nsIXPCSecurityManager
|
||||
[noscript] void checkSameOriginURI(in nsIURI aSourceURI,
|
||||
in nsIURI aTargetURI);
|
||||
|
||||
/**
|
||||
* Returns OK if aSourcePrincipal and aTargetPrincipal
|
||||
* have the same "origin" (scheme, host, and port).
|
||||
*/
|
||||
[noscript] void checkSameOriginPrincipal(in nsIPrincipal aSourcePrincipal,
|
||||
in nsIPrincipal aTargetPrincipal);
|
||||
|
||||
};
|
||||
|
||||
%{C++
|
||||
|
||||
@@ -556,6 +556,15 @@ nsScriptSecurityManager::CheckSameOriginURI(nsIURI* aSourceURI,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScriptSecurityManager::CheckSameOriginPrincipal(nsIPrincipal* aSourcePrincipal,
|
||||
nsIPrincipal* aTargetPrincipal)
|
||||
{
|
||||
return CheckSameOriginDOMProp(aSourcePrincipal, aTargetPrincipal,
|
||||
nsIXPCSecurityManager::ACCESS_SET_PROPERTY);
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsScriptSecurityManager::CheckPropertyAccessImpl(PRUint32 aAction,
|
||||
nsIXPCNativeCallContext* aCallContext,
|
||||
|
||||
@@ -67,6 +67,7 @@ class nsINodeInfoManager;
|
||||
class nsINameSpaceManager;
|
||||
class nsIDocument;
|
||||
class nsIURI;
|
||||
class nsIPrincipal;
|
||||
|
||||
|
||||
// IID for the nsINodeInfo interface
|
||||
@@ -287,6 +288,11 @@ public:
|
||||
*/
|
||||
NS_IMETHOD GetDocument(nsIDocument*& aDocument) const = 0;
|
||||
|
||||
/*
|
||||
* Retrieve a pointer to the principal for the document of this node info.
|
||||
*/
|
||||
NS_IMETHOD GetDocumentPrincipal(nsIPrincipal** aPrincipal) const = 0;
|
||||
|
||||
protected:
|
||||
/*
|
||||
* nsNodeInfoInner is used for two things:
|
||||
@@ -368,15 +374,15 @@ public:
|
||||
NS_IMETHOD GetDocument(nsIDocument*& aDocument) = 0;
|
||||
|
||||
/**
|
||||
* Gets the url of the document associated with this.
|
||||
* Gets the principal of the document associated with this.
|
||||
*/
|
||||
NS_IMETHOD GetDocumentURL(nsIURI** aURL) = 0;
|
||||
NS_IMETHOD GetDocumentPrincipal(nsIPrincipal** aPrincipal) = 0;
|
||||
|
||||
/**
|
||||
* Sets the url of the nodeinfo manager. This should only be called when
|
||||
* this nodeinfo manager isn't connected to an nsIDocument.
|
||||
* Sets the principal of the nodeinfo manager. This should only be called
|
||||
* when this nodeinfo manager isn't connected to an nsIDocument.
|
||||
*/
|
||||
NS_IMETHOD SetDocumentURL(nsIURI* aURL) = 0;
|
||||
NS_IMETHOD SetDocumentPrincipal(nsIPrincipal* aPrincipal) = 0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -379,12 +379,12 @@ nsContentUtils::CheckSameOrigin(nsIDOMNode *aTrustedNode,
|
||||
NS_PRECONDITION(aTrustedNode, "There must be a trusted node");
|
||||
|
||||
/*
|
||||
* Get hold of each node's document or uri
|
||||
* Get hold of each node's document or principal
|
||||
*/
|
||||
|
||||
// In most cases this is a document, so lets try that first
|
||||
nsCOMPtr<nsIDocument> trustedDoc = do_QueryInterface(aTrustedNode);
|
||||
nsCOMPtr<nsIURI> trustedUri;
|
||||
nsCOMPtr<nsIPrincipal> trustedPrincipal;
|
||||
|
||||
if (!trustedDoc) {
|
||||
#ifdef DEBUG
|
||||
@@ -396,7 +396,7 @@ nsContentUtils::CheckSameOrigin(nsIDOMNode *aTrustedNode,
|
||||
aTrustedNode->GetOwnerDocument(getter_AddRefs(domDoc));
|
||||
if (!domDoc) {
|
||||
// In theory this should never happen. But since theory and reality are
|
||||
// different for XUL elements we'll try to get the URI from the
|
||||
// different for XUL elements we'll try to get the principal from the
|
||||
// nsINodeInfoManager.
|
||||
|
||||
nsCOMPtr<nsIContent> cont = do_QueryInterface(aTrustedNode);
|
||||
@@ -406,12 +406,11 @@ nsContentUtils::CheckSameOrigin(nsIDOMNode *aTrustedNode,
|
||||
cont->GetNodeInfo(*getter_AddRefs(ni));
|
||||
NS_ENSURE_TRUE(ni, NS_ERROR_UNEXPECTED);
|
||||
|
||||
nsCOMPtr<nsINodeInfoManager> nimgr;
|
||||
ni->GetNodeInfoManager(*getter_AddRefs(nimgr));
|
||||
nimgr->GetDocumentURL(getter_AddRefs(trustedUri));
|
||||
ni->GetDocumentPrincipal(getter_AddRefs(trustedPrincipal));
|
||||
|
||||
if (!trustedUri) {
|
||||
// Can't get uri of aTrustedNode so we can't check security against it
|
||||
if (!trustedPrincipal) {
|
||||
// Can't get principal of aTrustedNode so we can't check security
|
||||
// against it
|
||||
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
@@ -429,7 +428,7 @@ nsContentUtils::CheckSameOrigin(nsIDOMNode *aTrustedNode,
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(aUnTrustedNode);
|
||||
|
||||
nsCOMPtr<nsIDocument> unTrustedDoc;
|
||||
nsCOMPtr<nsIURI> unTrustedUri;
|
||||
nsCOMPtr<nsIPrincipal> unTrustedPrincipal;
|
||||
|
||||
if (!content) {
|
||||
unTrustedDoc = do_QueryInterface(aUnTrustedNode);
|
||||
@@ -447,21 +446,21 @@ nsContentUtils::CheckSameOrigin(nsIDOMNode *aTrustedNode,
|
||||
nsCOMPtr<nsIDOMDocument> domDoc;
|
||||
aUnTrustedNode->GetOwnerDocument(getter_AddRefs(domDoc));
|
||||
if (!domDoc) {
|
||||
// if we can't get a doc then lets try to get uri through nodeinfo
|
||||
// if we can't get a doc then lets try to get principal through nodeinfo
|
||||
// manager
|
||||
nsCOMPtr<nsINodeInfo> ni;
|
||||
content->GetNodeInfo(*getter_AddRefs(ni));
|
||||
if (!ni) {
|
||||
// we can't get to the uri so we'll give up and give the caller access
|
||||
// we can't get to the principal so we'll give up and give the caller
|
||||
// access
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsINodeInfoManager> nimgr;
|
||||
ni->GetNodeInfoManager(*getter_AddRefs(nimgr));
|
||||
nimgr->GetDocumentURL(getter_AddRefs(unTrustedUri));
|
||||
if (!unTrustedUri) {
|
||||
// we can't get to the uri so we'll give up and give the caller access
|
||||
ni->GetDocumentPrincipal(getter_AddRefs(unTrustedPrincipal));
|
||||
|
||||
if (!unTrustedPrincipal) {
|
||||
// we can't get to the principal so we'll give up and give the caller access
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@@ -473,31 +472,31 @@ nsContentUtils::CheckSameOrigin(nsIDOMNode *aTrustedNode,
|
||||
}
|
||||
|
||||
/*
|
||||
* Compare the uris
|
||||
* Compare the principals
|
||||
*/
|
||||
|
||||
// If they are in the same document then everything is just fine
|
||||
if (trustedDoc == unTrustedDoc && trustedDoc)
|
||||
return NS_OK;
|
||||
|
||||
if (!trustedUri) {
|
||||
trustedDoc->GetDocumentURL(getter_AddRefs(trustedUri));
|
||||
// If the trusted node doesn't have a uri we can't check security against it
|
||||
if (!trustedUri) {
|
||||
if (!trustedPrincipal) {
|
||||
trustedDoc->GetPrincipal(getter_AddRefs(trustedPrincipal));
|
||||
if (!trustedPrincipal) {
|
||||
// If the trusted node doesn't have a principal we can't check security against it
|
||||
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
}
|
||||
}
|
||||
// Chrome can do anything
|
||||
PRBool isChrome;
|
||||
nsresult rv = trustedUri->SchemeIs("chrome", &isChrome);
|
||||
if (NS_SUCCEEDED(rv) && isChrome) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!unTrustedUri) {
|
||||
unTrustedDoc->GetDocumentURL(getter_AddRefs(unTrustedUri));
|
||||
// If the untrusted node doesn't have a uri we'll allow it to be accessed.
|
||||
if (!unTrustedUri) {
|
||||
if (!unTrustedPrincipal) {
|
||||
unTrustedDoc->GetPrincipal(getter_AddRefs(unTrustedPrincipal));
|
||||
if (!unTrustedDoc) {
|
||||
// We can't get hold of the principal for this node. This should happen
|
||||
// very rarely, like for textnodes out of the tree and <option>s created
|
||||
// using 'new Option'.
|
||||
// If we didn't allow access to nodes like this you wouldn't be able to
|
||||
// insert these nodes into a document.
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
@@ -508,24 +507,38 @@ nsContentUtils::CheckSameOrigin(nsIDOMNode *aTrustedNode,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return sSecurityManager->CheckSameOriginURI(trustedUri, unTrustedUri);
|
||||
return sSecurityManager->CheckSameOriginPrincipal(trustedPrincipal,
|
||||
unTrustedPrincipal);
|
||||
}
|
||||
|
||||
// static
|
||||
PRBool
|
||||
nsContentUtils::CanCallerAccess(nsIDOMNode *aNode)
|
||||
{
|
||||
if (!sSecurityManager) {
|
||||
// No security manager available, let any calls go through...
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrincipal> subjectPrincipal;
|
||||
sSecurityManager->GetSubjectPrincipal(getter_AddRefs(subjectPrincipal));
|
||||
|
||||
if (!subjectPrincipal) {
|
||||
// we're running as system, grant access to the node.
|
||||
|
||||
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<nsIPrincipal> principal;
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(aNode));
|
||||
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
|
||||
if (!content) {
|
||||
doc = do_QueryInterface(aNode);
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(aNode);
|
||||
|
||||
if (!doc) {
|
||||
// aNode is neither a nsIContent nor an nsIDocument, something
|
||||
@@ -535,31 +548,41 @@ nsContentUtils::CanCallerAccess(nsIDOMNode *aNode)
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
doc->GetPrincipal(getter_AddRefs(principal));
|
||||
}
|
||||
|
||||
if (!doc) {
|
||||
else {
|
||||
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;
|
||||
nsCOMPtr<nsINodeInfo> ni;
|
||||
content->GetNodeInfo(*getter_AddRefs(ni));
|
||||
if (!ni) {
|
||||
// aNode is not part of a document, let any caller access it.
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
ni->GetDocumentPrincipal(getter_AddRefs(principal));
|
||||
}
|
||||
else {
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
|
||||
NS_ASSERTION(doc, "QI to nsIDocument failed");
|
||||
doc->GetPrincipal(getter_AddRefs(principal));
|
||||
}
|
||||
|
||||
doc = do_QueryInterface(domDoc);
|
||||
|
||||
NS_ASSERTION(doc, "QI to nsIDocument failed");
|
||||
}
|
||||
|
||||
if (!sSecurityManager) {
|
||||
// No security manager available, let any calls go through...
|
||||
if (!principal) {
|
||||
// We can't get hold of the principal for this node. This should happen
|
||||
// very rarely, like for textnodes out of the tree and <option>s created
|
||||
// using 'new Option'.
|
||||
// If we didn't allow access to nodes like this you wouldn't be able to
|
||||
// insert these nodes into a document.
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
doc->GetDocumentURL(getter_AddRefs(uri));
|
||||
|
||||
nsresult rv = sSecurityManager->CheckSameOrigin(nsnull, uri);
|
||||
nsresult rv = sSecurityManager->CheckSameOriginPrincipal(subjectPrincipal,
|
||||
principal);
|
||||
|
||||
return NS_SUCCEEDED(rv);
|
||||
}
|
||||
|
||||
@@ -325,3 +325,8 @@ nsNodeInfo::GetDocument(nsIDocument*& aDocument) const
|
||||
return mOwnerManager->GetDocument(aDocument);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNodeInfo::GetDocumentPrincipal(nsIPrincipal** aPrincipal) const
|
||||
{
|
||||
return mOwnerManager->GetDocumentPrincipal(aPrincipal);
|
||||
}
|
||||
|
||||
@@ -72,6 +72,7 @@ public:
|
||||
NS_IMETHOD NameChanged(nsIAtom *aName, nsINodeInfo*& aResult);
|
||||
NS_IMETHOD PrefixChanged(nsIAtom *aPrefix, nsINodeInfo*& aResult);
|
||||
NS_IMETHOD GetDocument(nsIDocument*& aDocument) const;
|
||||
NS_IMETHOD GetDocumentPrincipal(nsIPrincipal** aPrincipal) const;
|
||||
|
||||
// nsNodeInfo
|
||||
nsNodeInfo();
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#include "nsString.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIPrincipal.h"
|
||||
|
||||
nsNodeInfoManager* nsNodeInfoManager::gAnonymousNodeInfoManager = nsnull;
|
||||
PRUint32 nsNodeInfoManager::gNodeManagerCount = 0;
|
||||
@@ -155,7 +156,7 @@ nsNodeInfoManager::Init(nsIDocument *aDocument,
|
||||
mDocument = aDocument;
|
||||
mNameSpaceManager = aNameSpaceManager;
|
||||
if (aDocument) {
|
||||
mDocumentURL = nsnull;
|
||||
mPrincipal = nsnull;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@@ -166,7 +167,17 @@ NS_IMETHODIMP
|
||||
nsNodeInfoManager::DropDocumentReference()
|
||||
{
|
||||
if (mDocument) {
|
||||
mDocument->GetDocumentURL(getter_AddRefs(mDocumentURL));
|
||||
// If the document has a uri we'll ask for it's principal. Otherwise we'll
|
||||
// consider this document 'anonymous'. We don't want to call GetPrincipal
|
||||
// on a document that doesn't have a URI since that'll give an assertion
|
||||
// that we're creating a principal without having a uri.
|
||||
// This happens in a few cases where a document is created and then
|
||||
// immediately dropped without ever getting a URI.
|
||||
nsCOMPtr<nsIURI> docUri;
|
||||
mDocument->GetDocumentURL(getter_AddRefs(docUri));
|
||||
if (docUri) {
|
||||
mDocument->GetPrincipal(getter_AddRefs(mPrincipal));
|
||||
}
|
||||
}
|
||||
mDocument = nsnull;
|
||||
|
||||
@@ -335,25 +346,33 @@ nsNodeInfoManager::GetDocument(nsIDocument*& aDocument)
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNodeInfoManager::GetDocumentURL(nsIURI** aURL)
|
||||
nsNodeInfoManager::GetDocumentPrincipal(nsIPrincipal** aPrincipal)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aURL);
|
||||
NS_ASSERTION(!mDocument || !mDocumentURL,
|
||||
"how'd we end up with both a document and a url?");
|
||||
NS_ENSURE_ARG_POINTER(aPrincipal);
|
||||
NS_ASSERTION(!mDocument || !mPrincipal,
|
||||
"how'd we end up with both a document and a principal?");
|
||||
|
||||
if (mDocument) {
|
||||
return mDocument->GetDocumentURL(aURL);
|
||||
// If the document has a uri we'll ask for it's principal. Otherwise we'll
|
||||
// consider this document 'anonymous'
|
||||
nsCOMPtr<nsIURI> docUri;
|
||||
mDocument->GetDocumentURL(getter_AddRefs(docUri));
|
||||
if (!docUri) {
|
||||
*aPrincipal = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
return mDocument->GetPrincipal(aPrincipal);
|
||||
}
|
||||
*aURL = mDocumentURL;
|
||||
NS_IF_ADDREF(*aURL);
|
||||
*aPrincipal = mPrincipal;
|
||||
NS_IF_ADDREF(*aPrincipal);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNodeInfoManager::SetDocumentURL(nsIURI* aURL)
|
||||
nsNodeInfoManager::SetDocumentPrincipal(nsIPrincipal* aPrincipal)
|
||||
{
|
||||
NS_ENSURE_FALSE(mDocument, NS_ERROR_UNEXPECTED);
|
||||
mDocumentURL = aURL;
|
||||
mPrincipal = aPrincipal;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
#include "nsCOMPtr.h"
|
||||
#include "plhash.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsIPrincipal.h"
|
||||
|
||||
class nsNodeInfo;
|
||||
|
||||
@@ -71,8 +72,8 @@ public:
|
||||
nsINodeInfo*& aNodeInfo);
|
||||
NS_IMETHOD GetNamespaceManager(nsINameSpaceManager*& aNameSpaceManager);
|
||||
NS_IMETHOD GetDocument(nsIDocument*& aDocument);
|
||||
NS_IMETHOD GetDocumentURL(nsIURI** aURL);
|
||||
NS_IMETHOD SetDocumentURL(nsIURI* aURL);
|
||||
NS_IMETHOD GetDocumentPrincipal(nsIPrincipal** aPrincipal);
|
||||
NS_IMETHOD SetDocumentPrincipal(nsIPrincipal* aPrincipal);
|
||||
|
||||
// nsNodeInfoManager
|
||||
nsNodeInfoManager();
|
||||
@@ -91,7 +92,7 @@ private:
|
||||
PLHashTable *mNodeInfoHash;
|
||||
nsCOMPtr<nsINameSpaceManager> mNameSpaceManager;
|
||||
nsIDocument *mDocument; // WEAK
|
||||
nsCOMPtr<nsIURI> mDocumentURL;
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
|
||||
/*
|
||||
* gAnonymousNodeInfoManager is a global nodeinfo manager used for nodes
|
||||
|
||||
@@ -341,8 +341,16 @@ nsXULPrototypeDocument::Read(nsIObjectInputStream* aStream)
|
||||
if (! securityManager)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
rv |= securityManager->GetCodebasePrincipal(mURI, getter_AddRefs(mDocumentPrincipal));
|
||||
rv |= NS_ReadOptionalObject(aStream, PR_TRUE, getter_AddRefs(mDocumentPrincipal));
|
||||
if (!mDocumentPrincipal) {
|
||||
// XXX This should be handled by the security manager, see bug 160042
|
||||
PRBool isChrome = PR_FALSE;
|
||||
if (NS_SUCCEEDED(mURI->SchemeIs("chrome", &isChrome)) && isChrome)
|
||||
rv |= securityManager->GetSystemPrincipal(getter_AddRefs(mDocumentPrincipal));
|
||||
else
|
||||
rv |= securityManager->GetCodebasePrincipal(mURI, getter_AddRefs(mDocumentPrincipal));
|
||||
}
|
||||
mNodeInfoManager->SetDocumentPrincipal(mDocumentPrincipal);
|
||||
|
||||
// nsIScriptGlobalObject mGlobalObject
|
||||
mGlobalObject = new nsXULPDGlobalObject();
|
||||
@@ -440,9 +448,17 @@ nsXULPrototypeDocument::GetURI(nsIURI** aResult)
|
||||
NS_IMETHODIMP
|
||||
nsXULPrototypeDocument::SetURI(nsIURI* aURI)
|
||||
{
|
||||
NS_PRECONDITION(mNodeInfoManager, "missing nodeInfoManager");
|
||||
NS_ASSERTION(!mURI, "Can't change the uri of a xul prototype document");
|
||||
if (mURI)
|
||||
return NS_ERROR_ALREADY_INITIALIZED;
|
||||
|
||||
mURI = aURI;
|
||||
mNodeInfoManager->SetDocumentURL(aURI);
|
||||
if (!mDocumentPrincipal) {
|
||||
// If the document doesn't have a principal yet we'll force the creation of one
|
||||
// so that mNodeInfoManager properly gets one.
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
GetDocumentPrincipal(getter_AddRefs(principal));
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -527,6 +543,7 @@ nsXULPrototypeDocument::SetHeaderData(nsIAtom* aField, const nsAString& aData)
|
||||
NS_IMETHODIMP
|
||||
nsXULPrototypeDocument::GetDocumentPrincipal(nsIPrincipal** aResult)
|
||||
{
|
||||
NS_PRECONDITION(mNodeInfoManager, "missing nodeInfoManager");
|
||||
if (!mDocumentPrincipal) {
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIScriptSecurityManager> securityManager =
|
||||
@@ -535,10 +552,17 @@ nsXULPrototypeDocument::GetDocumentPrincipal(nsIPrincipal** aResult)
|
||||
if (NS_FAILED(rv))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
rv = securityManager->GetCodebasePrincipal(mURI, getter_AddRefs(mDocumentPrincipal));
|
||||
// XXX This should be handled by the security manager, see bug 160042
|
||||
PRBool isChrome = PR_FALSE;
|
||||
if (NS_SUCCEEDED(mURI->SchemeIs("chrome", &isChrome)) && isChrome)
|
||||
rv = securityManager->GetSystemPrincipal(getter_AddRefs(mDocumentPrincipal));
|
||||
else
|
||||
rv = securityManager->GetCodebasePrincipal(mURI, getter_AddRefs(mDocumentPrincipal));
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
mNodeInfoManager->SetDocumentPrincipal(mDocumentPrincipal);
|
||||
}
|
||||
|
||||
*aResult = mDocumentPrincipal;
|
||||
@@ -550,7 +574,9 @@ nsXULPrototypeDocument::GetDocumentPrincipal(nsIPrincipal** aResult)
|
||||
NS_IMETHODIMP
|
||||
nsXULPrototypeDocument::SetDocumentPrincipal(nsIPrincipal* aPrincipal)
|
||||
{
|
||||
NS_PRECONDITION(mNodeInfoManager, "missing nodeInfoManager");
|
||||
mDocumentPrincipal = aPrincipal;
|
||||
mNodeInfoManager->SetDocumentPrincipal(aPrincipal);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,8 @@
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsINodeInfo.h"
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -323,44 +325,76 @@ nsIScriptSecurityManager *gTxSecurityManager = 0;
|
||||
// static
|
||||
PRBool URIUtils::CanCallerAccess(nsIDOMNode *aNode)
|
||||
{
|
||||
if (!gTxSecurityManager) {
|
||||
// No security manager available, let any calls go through...
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrincipal> subjectPrincipal;
|
||||
gTxSecurityManager->GetSubjectPrincipal(getter_AddRefs(subjectPrincipal));
|
||||
|
||||
if (!subjectPrincipal) {
|
||||
// we're running as system, grant access to the node.
|
||||
|
||||
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;
|
||||
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(aNode));
|
||||
|
||||
if (!content) {
|
||||
doc = do_QueryInterface(aNode);
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(aNode);
|
||||
|
||||
if (!doc) {
|
||||
// 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;
|
||||
}
|
||||
doc->GetPrincipal(getter_AddRefs(principal));
|
||||
}
|
||||
|
||||
if (!doc) {
|
||||
else {
|
||||
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;
|
||||
nsCOMPtr<nsINodeInfo> ni;
|
||||
content->GetNodeInfo(*getter_AddRefs(ni));
|
||||
if (!ni) {
|
||||
// aNode is not part of a document, let any caller access it.
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
ni->GetDocumentPrincipal(getter_AddRefs(principal));
|
||||
}
|
||||
else {
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
|
||||
NS_ASSERTION(doc, "QI to nsIDocument failed");
|
||||
doc->GetPrincipal(getter_AddRefs(principal));
|
||||
}
|
||||
doc = do_QueryInterface(domDoc);
|
||||
NS_ASSERTION(doc, "QI to nsIDocument failed");
|
||||
}
|
||||
|
||||
if (!gTxSecurityManager) {
|
||||
// No security manager available, let any calls go through...
|
||||
if (!principal) {
|
||||
// We can't get hold of the principal for this node. This should happen
|
||||
// very rarely, like for textnodes out of the tree and <option>s created
|
||||
// using 'new Option'.
|
||||
// If we didn't allow access to nodes like this you wouldn't be able to
|
||||
// insert these nodes into a document.
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
doc->GetDocumentURL(getter_AddRefs(uri));
|
||||
nsresult rv = gTxSecurityManager->CheckSameOriginPrincipal(subjectPrincipal,
|
||||
principal);
|
||||
|
||||
return NS_SUCCEEDED(gTxSecurityManager->CheckSameOrigin(nsnull, uri));
|
||||
return NS_SUCCEEDED(rv);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user