Bug 284225: Use right security context for xslt. r/sr=peterv

This commit is contained in:
jonas@sicking.cc 2007-09-27 15:05:07 -07:00
parent df7831eb06
commit 738b69078c
5 changed files with 131 additions and 160 deletions

View File

@ -63,6 +63,7 @@ REQUIRES += \
unicharutil \
necko \
htmlparser \
caps \
$(NULL)
else
REQUIRES += expat

View File

@ -45,6 +45,7 @@
#include "nsIDOMDocument.h"
#include "nsSyncLoadService.h"
#include "nsNetUtil.h"
#include "nsIPrincipal.h"
#else
#include "expat_config.h"
#include "expat.h"
@ -98,8 +99,13 @@ txParseDocumentFromURI(const nsAString& aHref, const txXPathNode& aLoader,
nsIDocument* loaderDocument = txXPathNativeNode::getDocument(aLoader);
nsCOMPtr<nsILoadGroup> loadGroup = loaderDocument->GetDocumentLoadGroup();
nsIURI *loaderUri = loaderDocument->GetDocumentURI();
NS_ENSURE_TRUE(loaderUri, NS_ERROR_FAILURE);
nsCOMPtr<nsIURI> loaderUri;
rv = loaderDocument->NodePrincipal()->GetURI(getter_AddRefs(loaderUri));
NS_ENSURE_SUCCESS(rv, rv);
// For the system principal loaderUri will be null here, which is good
// since that means that chrome documents can load any uri.
// Raw pointer, we want the resulting txXPathNode to hold a reference to
// the document.

View File

@ -422,48 +422,16 @@ txStylesheetSink::GetInterface(const nsIID& aIID, void** aResult)
return QueryInterface(aIID, aResult);
}
static nsresult
CheckLoadURI(nsIURI *aUri, nsIURI *aReferrerUri,
nsIPrincipal *aReferrerPrincipal, nsISupports *aContext)
{
// First do a security check.
nsresult rv;
nsCOMPtr<nsIScriptSecurityManager> securityManager =
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = securityManager->
CheckLoadURIWithPrincipal(aReferrerPrincipal, aUri,
nsIScriptSecurityManager::STANDARD);
NS_ENSURE_SUCCESS(rv, NS_ERROR_XSLT_LOAD_BLOCKED_ERROR);
rv = securityManager->CheckSameOriginURI(aReferrerUri, aUri);
NS_ENSURE_SUCCESS(rv, NS_ERROR_XSLT_LOAD_BLOCKED_ERROR);
// Then do a content policy check.
PRInt16 decision = nsIContentPolicy::ACCEPT;
rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_STYLESHEET,
aUri, aReferrerPrincipal, aContext,
NS_LITERAL_CSTRING("application/xml"), nsnull,
&decision,
nsContentUtils::GetContentPolicy(),
nsContentUtils::GetSecurityManager());
NS_ENSURE_SUCCESS(rv, rv);
return NS_CP_REJECTED(decision) ? NS_ERROR_XSLT_LOAD_BLOCKED_ERROR : NS_OK;
}
class txCompileObserver : public txACompileObserver
{
public:
txCompileObserver(txMozillaXSLTProcessor* aProcessor,
nsILoadGroup* aLoadGroup,
nsIPrincipal* aCallerPrincipal);
nsILoadGroup* aLoadGroup);
TX_DECL_ACOMPILEOBSERVER;
nsresult startLoad(nsIURI* aUri, txStylesheetCompiler* aCompiler,
nsIURI* aReferrerURI);
nsIPrincipal* aSourcePrincipal);
protected:
nsAutoRefCnt mRefCnt;
@ -479,11 +447,9 @@ protected:
};
txCompileObserver::txCompileObserver(txMozillaXSLTProcessor* aProcessor,
nsILoadGroup* aLoadGroup,
nsIPrincipal* aCallerPrincipal)
nsILoadGroup* aLoadGroup)
: mProcessor(aProcessor),
mLoadGroup(aLoadGroup),
mCallerPrincipal(aCallerPrincipal)
mLoadGroup(aLoadGroup)
{
}
@ -521,11 +487,20 @@ txCompileObserver::loadURI(const nsAString& aUri,
rv = NS_NewURI(getter_AddRefs(referrerUri), aReferrerUri);
NS_ENSURE_SUCCESS(rv, rv);
// Do security check.
rv = CheckLoadURI(uri, referrerUri, mCallerPrincipal, nsnull);
nsCOMPtr<nsIPrincipal> referrerPrincipal;
rv = nsContentUtils::GetSecurityManager()->
GetCodebasePrincipal(referrerUri, getter_AddRefs(referrerPrincipal));
NS_ENSURE_SUCCESS(rv, rv);
return startLoad(uri, aCompiler, referrerUri);
// Do security check.
rv = nsContentUtils::
CheckSecurityBeforeLoad(uri, referrerPrincipal,
nsIScriptSecurityManager::STANDARD, PR_FALSE,
nsIContentPolicy::TYPE_STYLESHEET,
nsnull, NS_LITERAL_CSTRING("application/xml"));
NS_ENSURE_SUCCESS(rv, rv);
return startLoad(uri, aCompiler, referrerPrincipal);
}
void
@ -544,7 +519,7 @@ txCompileObserver::onDoneCompiling(txStylesheetCompiler* aCompiler,
nsresult
txCompileObserver::startLoad(nsIURI* aUri, txStylesheetCompiler* aCompiler,
nsIURI* aReferrerURI)
nsIPrincipal* aReferrerPrincipal)
{
nsCOMPtr<nsIChannel> channel;
nsresult rv = NS_NewChannel(getter_AddRefs(channel), aUri);
@ -560,8 +535,10 @@ txCompileObserver::startLoad(nsIURI* aUri, txStylesheetCompiler* aCompiler,
NS_LITERAL_CSTRING("text/xml,application/xml,application/xhtml+xml,*/*;q=0.1"),
PR_FALSE);
if (aReferrerURI) {
httpChannel->SetReferrer(aReferrerURI);
nsCOMPtr<nsIURI> referrerURI;
aReferrerPrincipal->GetURI(getter_AddRefs(referrerURI));
if (referrerURI) {
httpChannel->SetReferrer(referrerURI);
}
}
@ -588,24 +565,24 @@ TX_LoadSheet(nsIURI* aUri, txMozillaXSLTProcessor* aProcessor,
aUri->GetSpec(spec);
PR_LOG(txLog::xslt, PR_LOG_ALWAYS, ("TX_LoadSheet: %s\n", spec.get()));
nsCOMPtr<nsIURI> referrerURI;
aCallerPrincipal->GetURI(getter_AddRefs(referrerURI));
NS_ASSERTION(referrerURI, "Caller principal must have a URI!");
// Pass source document as the context
nsresult rv = CheckLoadURI(aUri, referrerURI, aCallerPrincipal,
aProcessor->GetSourceContentModel());
nsresult rv = nsContentUtils::
CheckSecurityBeforeLoad(aUri, aCallerPrincipal,
nsIScriptSecurityManager::STANDARD, PR_FALSE,
nsIContentPolicy::TYPE_STYLESHEET,
aProcessor->GetSourceContentModel(),
NS_LITERAL_CSTRING("application/xml"));
NS_ENSURE_SUCCESS(rv, rv);
nsRefPtr<txCompileObserver> observer =
new txCompileObserver(aProcessor, aLoadGroup, aCallerPrincipal);
new txCompileObserver(aProcessor, aLoadGroup);
NS_ENSURE_TRUE(observer, NS_ERROR_OUT_OF_MEMORY);
nsRefPtr<txStylesheetCompiler> compiler =
new txStylesheetCompiler(NS_ConvertUTF8toUTF16(spec), observer);
NS_ENSURE_TRUE(compiler, NS_ERROR_OUT_OF_MEMORY);
return observer->startLoad(aUri, compiler, referrerURI);
return observer->startLoad(aUri, compiler, aCallerPrincipal);
}
/**
@ -613,105 +590,88 @@ TX_LoadSheet(nsIURI* aUri, txMozillaXSLTProcessor* aProcessor,
* Observer needs to do synchronous loads.
*/
static nsresult
handleNode(nsIDOMNode* aNode, txStylesheetCompiler* aCompiler)
handleNode(nsINode* aNode, txStylesheetCompiler* aCompiler)
{
nsresult rv = NS_OK;
PRUint16 nodetype;
aNode->GetNodeType(&nodetype);
switch (nodetype) {
case nsIDOMNode::ELEMENT_NODE:
{
nsCOMPtr<nsIContent> element = do_QueryInterface(aNode);
if (aNode->IsNodeOfType(nsINode::eELEMENT)) {
nsIContent* element = static_cast<nsIContent*>(aNode);
PRUint32 attsCount = element->GetAttrCount();
nsAutoArrayPtr<txStylesheetAttr> atts;
if (attsCount > 0) {
atts = new txStylesheetAttr[attsCount];
NS_ENSURE_TRUE(atts, NS_ERROR_OUT_OF_MEMORY);
PRUint32 attsCount = element->GetAttrCount();
nsAutoArrayPtr<txStylesheetAttr> atts;
if (attsCount > 0) {
atts = new txStylesheetAttr[attsCount];
NS_ENSURE_TRUE(atts, NS_ERROR_OUT_OF_MEMORY);
PRUint32 counter;
for (counter = 0; counter < attsCount; ++counter) {
txStylesheetAttr& att = atts[counter];
const nsAttrName* name = element->GetAttrNameAt(counter);
att.mNamespaceID = name->NamespaceID();
att.mLocalName = name->LocalName();
att.mPrefix = name->GetPrefix();
element->GetAttr(att.mNamespaceID, att.mLocalName, att.mValue);
}
PRUint32 counter;
for (counter = 0; counter < attsCount; ++counter) {
txStylesheetAttr& att = atts[counter];
const nsAttrName* name = element->GetAttrNameAt(counter);
att.mNamespaceID = name->NamespaceID();
att.mLocalName = name->LocalName();
att.mPrefix = name->GetPrefix();
element->GetAttr(att.mNamespaceID, att.mLocalName, att.mValue);
}
nsINodeInfo *ni = element->NodeInfo();
rv = aCompiler->startElement(ni->NamespaceID(),
ni->NameAtom(),
ni->GetPrefixAtom(), atts,
attsCount);
NS_ENSURE_SUCCESS(rv, rv);
// explicitly destroy the attrs here since we no longer need it
atts = nsnull;
PRUint32 childCount = element->GetChildCount();
if (childCount > 0) {
PRUint32 counter = 0;
nsIContent *child;
while ((child = element->GetChildAt(counter++))) {
nsCOMPtr<nsIDOMNode> childNode = do_QueryInterface(child);
rv = handleNode(childNode, aCompiler);
NS_ENSURE_SUCCESS(rv, rv);
}
}
rv = aCompiler->endElement();
NS_ENSURE_SUCCESS(rv, rv);
break;
}
case nsIDOMNode::CDATA_SECTION_NODE:
case nsIDOMNode::TEXT_NODE:
{
nsAutoString chars;
aNode->GetNodeValue(chars);
rv = aCompiler->characters(chars);
NS_ENSURE_SUCCESS(rv, rv);
break;
}
case nsIDOMNode::DOCUMENT_NODE:
{
nsCOMPtr<nsIDocument> document = do_QueryInterface(aNode);
nsINodeInfo *ni = element->NodeInfo();
rv = aCompiler->startElement(ni->NamespaceID(),
ni->NameAtom(),
ni->GetPrefixAtom(), atts,
attsCount);
NS_ENSURE_SUCCESS(rv, rv);
// explicitly destroy the attrs here since we no longer need it
atts = nsnull;
PRUint32 childCount = element->GetChildCount();
if (childCount > 0) {
PRUint32 counter = 0;
nsIContent *child;
while ((child = document->GetChildAt(counter++))) {
nsCOMPtr<nsIDOMNode> childNode = do_QueryInterface(child);
rv = handleNode(childNode, aCompiler);
while ((child = element->GetChildAt(counter++))) {
rv = handleNode(child, aCompiler);
NS_ENSURE_SUCCESS(rv, rv);
}
break;
}
rv = aCompiler->endElement();
NS_ENSURE_SUCCESS(rv, rv);
}
else if (aNode->IsNodeOfType(nsINode::eTEXT)) {
nsAutoString chars;
static_cast<nsIContent*>(aNode)->AppendTextTo(chars);
rv = aCompiler->characters(chars);
NS_ENSURE_SUCCESS(rv, rv);
}
else if (aNode->IsNodeOfType(nsINode::eDOCUMENT)) {
nsIDocument* document = static_cast<nsIDocument*>(aNode);
PRUint32 counter = 0;
nsIContent *child;
while ((child = document->GetChildAt(counter++))) {
rv = handleNode(child, aCompiler);
NS_ENSURE_SUCCESS(rv, rv);
}
}
return NS_OK;
}
class txSyncCompileObserver : public txACompileObserver
{
public:
txSyncCompileObserver(txMozillaXSLTProcessor* aProcessor,
nsIPrincipal* aCallerPrincipal);
txSyncCompileObserver(txMozillaXSLTProcessor* aProcessor);
TX_DECL_ACOMPILEOBSERVER;
protected:
nsRefPtr<txMozillaXSLTProcessor> mProcessor;
nsCOMPtr<nsIPrincipal> mCallerPrincipal;
nsAutoRefCnt mRefCnt;
};
txSyncCompileObserver::txSyncCompileObserver(txMozillaXSLTProcessor* aProcessor,
nsIPrincipal* aCallerPrincipal)
: mProcessor(aProcessor),
mCallerPrincipal(aCallerPrincipal)
txSyncCompileObserver::txSyncCompileObserver(txMozillaXSLTProcessor* aProcessor)
: mProcessor(aProcessor)
{
}
@ -749,7 +709,16 @@ txSyncCompileObserver::loadURI(const nsAString& aUri,
rv = NS_NewURI(getter_AddRefs(referrerUri), aReferrerUri);
NS_ENSURE_SUCCESS(rv, rv);
rv = CheckLoadURI(uri, referrerUri, mCallerPrincipal, nsnull);
nsCOMPtr<nsIPrincipal> referrerPrincipal;
rv = nsContentUtils::GetSecurityManager()->
GetCodebasePrincipal(referrerUri, getter_AddRefs(referrerPrincipal));
NS_ENSURE_SUCCESS(rv, rv);
rv = nsContentUtils::
CheckSecurityBeforeLoad(uri, referrerPrincipal,
nsIScriptSecurityManager::STANDARD,
PR_FALSE, nsIContentPolicy::TYPE_STYLESHEET,
nsnull, NS_LITERAL_CSTRING("application/xml"));
NS_ENSURE_SUCCESS(rv, rv);
// This is probably called by js, a loadGroup for the channel doesn't
@ -758,7 +727,9 @@ txSyncCompileObserver::loadURI(const nsAString& aUri,
rv = nsSyncLoadService::LoadDocument(uri, referrerUri, nsnull, PR_FALSE,
getter_AddRefs(document));
NS_ENSURE_SUCCESS(rv, rv);
rv = handleNode(document, aCompiler);
nsCOMPtr<nsIDocument> doc = do_QueryInterface(document);
rv = handleNode(doc, aCompiler);
if (NS_FAILED(rv)) {
nsCAutoString spec;
uri->GetSpec(spec);
@ -778,27 +749,22 @@ void txSyncCompileObserver::onDoneCompiling(txStylesheetCompiler* aCompiler,
}
nsresult
TX_CompileStylesheet(nsIDOMNode* aNode, txMozillaXSLTProcessor* aProcessor,
TX_CompileStylesheet(nsINode* aNode, txMozillaXSLTProcessor* aProcessor,
nsIPrincipal* aCallerPrincipal,
txStylesheet** aStylesheet)
{
// If we move GetBaseURI to nsINode this can be simplified.
nsCOMPtr<nsIDocument> doc = aNode->GetOwnerDoc();
NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
nsCOMPtr<nsIURI> uri;
nsCOMPtr<nsIDocument> doc;
nsCOMPtr<nsIContent> cont = do_QueryInterface(aNode);
if (cont) {
doc = cont->GetOwnerDoc();
NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
uri = cont->GetBaseURI();
if (aNode->IsNodeOfType(nsINode::eCONTENT)) {
uri = static_cast<nsIContent*>(aNode)->GetBaseURI();
}
else {
doc = do_QueryInterface(aNode);
NS_ASSERTION(doc, "aNode should be a doc or an element by now");
uri = doc->GetBaseURI();
else {
NS_ASSERTION(aNode->IsNodeOfType(nsINode::eDOCUMENT), "not a doc");
uri = static_cast<nsIDocument*>(aNode)->GetBaseURI();
}
NS_ENSURE_TRUE(uri, NS_ERROR_FAILURE);
nsCAutoString spec;
@ -812,7 +778,7 @@ TX_CompileStylesheet(nsIDOMNode* aNode, txMozillaXSLTProcessor* aProcessor,
NS_ConvertUTF8toUTF16 stylesheetURI(spec);
nsRefPtr<txSyncCompileObserver> obs =
new txSyncCompileObserver(aProcessor, aCallerPrincipal);
new txSyncCompileObserver(aProcessor);
NS_ENSURE_TRUE(obs, NS_ERROR_OUT_OF_MEMORY);
nsRefPtr<txStylesheetCompiler> compiler =

View File

@ -338,7 +338,8 @@ txMozillaXSLTProcessor::TransformDocument(nsIDOMNode* aSourceDOM,
type == nsIDOMNode::DOCUMENT_NODE,
NS_ERROR_INVALID_ARG);
nsresult rv = TX_CompileStylesheet(aStyleDOM, this, mPrincipal,
nsCOMPtr<nsINode> styleNode = do_QueryInterface(aStyleDOM);
nsresult rv = TX_CompileStylesheet(styleNode, this, mPrincipal,
getter_AddRefs(mStylesheet));
NS_ENSURE_SUCCESS(rv, rv);
@ -586,29 +587,25 @@ txMozillaXSLTProcessor::ImportStylesheet(nsIDOMNode *aStyle)
return NS_ERROR_DOM_SECURITY_ERR;
}
PRUint16 type = 0;
aStyle->GetNodeType(&type);
NS_ENSURE_TRUE(type == nsIDOMNode::ELEMENT_NODE ||
type == nsIDOMNode::DOCUMENT_NODE,
nsCOMPtr<nsINode> styleNode = do_QueryInterface(aStyle);
NS_ENSURE_TRUE(styleNode &&
(styleNode->IsNodeOfType(nsINode::eELEMENT) ||
styleNode->IsNodeOfType(nsINode::eDOCUMENT)),
NS_ERROR_INVALID_ARG);
nsresult rv = TX_CompileStylesheet(aStyle, this, mPrincipal,
nsresult rv = TX_CompileStylesheet(styleNode, this, mPrincipal,
getter_AddRefs(mStylesheet));
// XXX set up exception context, bug 204658
NS_ENSURE_SUCCESS(rv, rv);
if (type == nsIDOMNode::ELEMENT_NODE) {
nsCOMPtr<nsIDOMDocument> domDoc;
aStyle->GetOwnerDocument(getter_AddRefs(domDoc));
NS_ENSURE_TRUE(domDoc, NS_ERROR_UNEXPECTED);
if (styleNode->IsNodeOfType(nsINode::eELEMENT)) {
mStylesheetDocument = styleNode->GetOwnerDoc();
NS_ENSURE_TRUE(mStylesheetDocument, NS_ERROR_UNEXPECTED);
nsCOMPtr<nsIDocument> styleDoc = do_QueryInterface(domDoc);
mStylesheetDocument = styleDoc;
mEmbeddedStylesheetRoot = do_QueryInterface(aStyle);
mEmbeddedStylesheetRoot = static_cast<nsIContent*>(styleNode.get());
}
else {
nsCOMPtr<nsIDocument> styleDoc = do_QueryInterface(aStyle);
mStylesheetDocument = styleDoc;
mStylesheetDocument = static_cast<nsIDocument*>(styleNode.get());
}
mStylesheetDocument->AddMutationObserver(this);
@ -1173,10 +1170,11 @@ txMozillaXSLTProcessor::ensureStylesheet()
NS_ENSURE_TRUE(mStylesheetDocument, NS_ERROR_NOT_INITIALIZED);
nsCOMPtr<nsIDOMNode> style = do_QueryInterface(mEmbeddedStylesheetRoot);
nsINode* style = mEmbeddedStylesheetRoot;
if (!style) {
style = do_QueryInterface(mStylesheetDocument);
style = mStylesheetDocument;
}
return TX_CompileStylesheet(style, this, mPrincipal,
getter_AddRefs(mStylesheet));
}

View File

@ -171,7 +171,7 @@ extern nsresult TX_LoadSheet(nsIURI* aUri, txMozillaXSLTProcessor* aProcessor,
nsILoadGroup* aLoadGroup,
nsIPrincipal* aCallerPrincipal);
extern nsresult TX_CompileStylesheet(nsIDOMNode* aNode,
extern nsresult TX_CompileStylesheet(nsINode* aNode,
txMozillaXSLTProcessor* aProcessor,
nsIPrincipal* aCallerPrincipal,
txStylesheet** aStylesheet);