diff --git a/mozilla/content/base/public/nsContentUtils.h b/mozilla/content/base/public/nsContentUtils.h index 85e34d0bb3b..9086da893b1 100644 --- a/mozilla/content/base/public/nsContentUtils.h +++ b/mozilla/content/base/public/nsContentUtils.h @@ -531,6 +531,7 @@ public: * @param aURI uri of the image to be loaded * @param aContext the context the image is loaded in (eg an element) * @param aLoadingDocument the document we belong to + * @param aLoadingPrincipal the principal doing the load * @param aImageBlockingStatus the nsIContentPolicy blocking status for this * image. This will be set even if a security check fails for the * image, to some reasonable REJECT_* value. This out param will only @@ -543,18 +544,22 @@ public: static PRBool CanLoadImage(nsIURI* aURI, nsISupports* aContext, nsIDocument* aLoadingDocument, + nsIPrincipal* aLoadingPrincipal, PRInt16* aImageBlockingStatus = nsnull); /** * Method to start an image load. This does not do any security checks. * * @param aURI uri of the image to be loaded * @param aLoadingDocument the document we belong to + * @param aLoadingPrincipal the principal doing the load + * @param aReferrer the referrer URI * @param aObserver the observer for the image load * @param aLoadFlags the load flags to use. See nsIRequest * @return the imgIRequest for the image load */ static nsresult LoadImage(nsIURI* aURI, nsIDocument* aLoadingDocument, + nsIPrincipal* aLoadingPrincipal, nsIURI* aReferrer, imgIDecoderObserver* aObserver, PRInt32 aLoadFlags, diff --git a/mozilla/content/base/src/nsContentUtils.cpp b/mozilla/content/base/src/nsContentUtils.cpp index e9b05ef468d..61d9f912d32 100644 --- a/mozilla/content/base/src/nsContentUtils.cpp +++ b/mozilla/content/base/src/nsContentUtils.cpp @@ -2056,10 +2056,12 @@ nsContentUtils::SplitExpatName(const PRUnichar *aExpatName, nsIAtom **aPrefix, PRBool nsContentUtils::CanLoadImage(nsIURI* aURI, nsISupports* aContext, nsIDocument* aLoadingDocument, + nsIPrincipal* aLoadingPrincipal, PRInt16* aImageBlockingStatus) { NS_PRECONDITION(aURI, "Must have a URI"); NS_PRECONDITION(aLoadingDocument, "Must have a document"); + NS_PRECONDITION(aLoadingPrincipal, "Must have a loading principal"); nsresult rv; @@ -2084,9 +2086,10 @@ nsContentUtils::CanLoadImage(nsIURI* aURI, nsISupports* aContext, if (appType != nsIDocShell::APP_TYPE_EDITOR) { // Editor apps get special treatment here, editors can load images - // from anywhere. + // from anywhere. This allows editor to insert images from file:// + // into documents that are being edited. rv = sSecurityManager-> - CheckLoadURIWithPrincipal(aLoadingDocument->NodePrincipal(), aURI, + CheckLoadURIWithPrincipal(aLoadingPrincipal, aURI, nsIScriptSecurityManager::ALLOW_CHROME); if (NS_FAILED(rv)) { if (aImageBlockingStatus) { @@ -2098,11 +2101,15 @@ nsContentUtils::CanLoadImage(nsIURI* aURI, nsISupports* aContext, } } + nsCOMPtr loadingURI; + nsresult rv = aLoadingPrincipal->GetURI(getter_AddRefs(loadingURI)); + NS_ENSURE_SUCCESS(rv, PR_FALSE); + PRInt16 decision = nsIContentPolicy::ACCEPT; rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_IMAGE, aURI, - aLoadingDocument->GetDocumentURI(), + loadingURI, aContext, EmptyCString(), //mime guess nsnull, //extra @@ -2119,11 +2126,13 @@ nsContentUtils::CanLoadImage(nsIURI* aURI, nsISupports* aContext, // static nsresult nsContentUtils::LoadImage(nsIURI* aURI, nsIDocument* aLoadingDocument, - nsIURI* aReferrer, imgIDecoderObserver* aObserver, - PRInt32 aLoadFlags, imgIRequest** aRequest) + nsIPrincipal* aLoadingPrincipal, nsIURI* aReferrer, + imgIDecoderObserver* aObserver, PRInt32 aLoadFlags, + imgIRequest** aRequest) { NS_PRECONDITION(aURI, "Must have a URI"); NS_PRECONDITION(aLoadingDocument, "Must have a document"); + NS_PRECONDITION(aLoadingPrincipal, "Must have a principal"); NS_PRECONDITION(aRequest, "Null out param"); if (!sImgLoader) { @@ -2136,6 +2145,9 @@ nsContentUtils::LoadImage(nsIURI* aURI, nsIDocument* aLoadingDocument, nsIURI *documentURI = aLoadingDocument->GetDocumentURI(); + // We don't use aLoadingPrincipal for anything here yet... but we + // will. See bug 377092. + // XXXbz using "documentURI" for the initialDocumentURI is not quite // right, but the best we can do here... return sImgLoader->LoadImage(aURI, /* uri to load */ diff --git a/mozilla/content/base/src/nsImageLoadingContent.cpp b/mozilla/content/base/src/nsImageLoadingContent.cpp index 94b0bbf56d4..56277fc3f1f 100644 --- a/mozilla/content/base/src/nsImageLoadingContent.cpp +++ b/mozilla/content/base/src/nsImageLoadingContent.cpp @@ -533,6 +533,15 @@ nsImageLoadingContent::LoadImage(nsIURI* aNewURI, // sure to notify if it does. AutoStateChanger changer(this, aNotify); + // Use the principal of aDocument to avoid having to QI |this| an extra time. + // It should be the same as the principal of this node in any case. +#ifdef DEBUG + nsCOMPtr thisContent = do_QueryInterface(this); + NS_ASSERTION(thisContent && + thisContent->NodePrincipal() == aDocument->NodePrincipal(), + "Principal mismatch?"); +#endif + // If we'll be loading a new image, we want to cancel our existing // requests; the question is what reason to pass in. If everything // is going smoothly, that reason should be @@ -543,6 +552,7 @@ nsImageLoadingContent::LoadImage(nsIURI* aNewURI, PRInt16 newImageStatus; PRBool loadImage = nsContentUtils::CanLoadImage(aNewURI, this, aDocument, + aDocument->NodePrincipal(), &newImageStatus); NS_ASSERTION(loadImage || !NS_CP_ACCEPTED(newImageStatus), "CanLoadImage lied"); @@ -569,6 +579,7 @@ nsImageLoadingContent::LoadImage(nsIURI* aNewURI, nsCOMPtr & req = mCurrentRequest ? mPendingRequest : mCurrentRequest; rv = nsContentUtils::LoadImage(aNewURI, aDocument, + aDocument->NodePrincipal(), aDocument->GetDocumentURI(), this, aLoadFlags, getter_AddRefs(req)); diff --git a/mozilla/content/xbl/src/nsXBLResourceLoader.cpp b/mozilla/content/xbl/src/nsXBLResourceLoader.cpp index 3cdbb9418f2..8c435ad9cc3 100644 --- a/mozilla/content/xbl/src/nsXBLResourceLoader.cpp +++ b/mozilla/content/xbl/src/nsXBLResourceLoader.cpp @@ -122,7 +122,7 @@ nsXBLResourceLoader::LoadResources(PRBool* aResult) continue; if (curr->mType == nsGkAtoms::image) { - if (!nsContentUtils::CanLoadImage(url, doc, doc)) { + if (!nsContentUtils::CanLoadImage(url, doc, doc, doc->NodePrincipal())) { // We're not permitted to load this image, move on... continue; } @@ -131,7 +131,7 @@ nsXBLResourceLoader::LoadResources(PRBool* aResult) // Passing NULL for pretty much everything -- cause we don't care! // XXX: initialDocumentURI is NULL! nsCOMPtr req; - nsContentUtils::LoadImage(url, doc, docURL, nsnull, + nsContentUtils::LoadImage(url, doc, doc->NodePrincipal(), docURL, nsnull, nsIRequest::LOAD_BACKGROUND, getter_AddRefs(req)); } diff --git a/mozilla/layout/style/nsCSSStyleSheet.cpp b/mozilla/layout/style/nsCSSStyleSheet.cpp index ba2b2e65b82..dccc4d6a678 100644 --- a/mozilla/layout/style/nsCSSStyleSheet.cpp +++ b/mozilla/layout/style/nsCSSStyleSheet.cpp @@ -1138,7 +1138,7 @@ NS_IMETHODIMP nsCSSStyleSheet::GetStyleRuleAt(PRInt32 aIndex, nsICSSRule*& aRule) const { // Important: If this function is ever made scriptable, we must add - // a security check here. See GetCSSRules below for an example. + // a security check here. See GetCssRules below for an example. aRule = mInner->mOrderedRules.SafeObjectAt(aIndex); if (aRule) { NS_ADDREF(aRule); @@ -1321,6 +1321,35 @@ nsCSSStyleSheet::DidDirty() mDirty = PR_TRUE; } +nsresult +nsCSSStyleSheet::SubjectSubsumesInnerPrincipal() const +{ + // Get the security manager and do the subsumes check + nsIScriptSecurityManager *securityManager = + nsContentUtils::GetSecurityManager(); + + nsCOMPtr subjectPrincipal; + securityManager->GetSubjectPrincipal(getter_AddRefs(subjectPrincipal)); + + if (!subjectPrincipal) { + return NS_OK; + } + + PRBool subsumes; + nsresult rv = subjectPrincipal->Subsumes(mInner->mPrincipal, &subsumes); + NS_ENSURE_SUCCESS(rv, rv); + + if (subsumes) { + return NS_OK; + } + + if (!nsContentUtils::IsCallerTrustedForWrite()) { + return NS_ERROR_DOM_SECURITY_ERR; + } + + return NS_OK; +} + NS_IMETHODIMP nsCSSStyleSheet::IsModified(PRBool* aSheetModified) const { @@ -1454,27 +1483,8 @@ nsCSSStyleSheet::GetCssRules(nsIDOMCSSRuleList** aCssRules) //-- Security check: Only scripts whose principal subsumes that of the // style sheet can access rule collections. - - // Get the security manager and do the subsumes check - nsIScriptSecurityManager *securityManager = - nsContentUtils::GetSecurityManager(); - - nsCOMPtr subjectPrincipal; - securityManager->GetSubjectPrincipal(getter_AddRefs(subjectPrincipal)); - - nsresult rv = NS_OK; - if (subjectPrincipal) { - PRBool subsumes; - rv = subjectPrincipal->Subsumes(mInner->mPrincipal, &subsumes); - if (NS_SUCCEEDED(rv) && !subsumes && - !nsContentUtils::IsCallerTrustedForRead()) { - rv = NS_ERROR_DOM_SECURITY_ERR; - } - - if (NS_FAILED(rv)) { - return rv; - } - } + nsresult rv = SubjectSubsumesInnerPrincipal(); + NS_ENSURE_SUCCESS(rv, rv); // OK, security check passed, so get the rule collection if (nsnull == mRuleCollection) { @@ -1503,6 +1513,11 @@ nsCSSStyleSheet::InsertRule(const nsAString& aRule, return NS_ERROR_DOM_INVALID_ACCESS_ERR; } + //-- Security check: Only scripts whose principal subsumes that of the + // style sheet can modify rule collections. + nsresult rv = SubjectSubsumesInnerPrincipal(); + NS_ENSURE_SUCCESS(rv, rv); + if (aRule.IsEmpty()) { // Nothing to do here return NS_OK; @@ -1673,6 +1688,11 @@ nsCSSStyleSheet::DeleteRule(PRUint32 aIndex) return NS_ERROR_DOM_INVALID_ACCESS_ERR; } + //-- Security check: Only scripts whose principal subsumes that of the + // style sheet can modify rule collections. + nsresult rv = SubjectSubsumesInnerPrincipal(); + NS_ENSURE_SUCCESS(rv, rv); + // XXX TBI: handle @rule types mozAutoDocUpdate updateBatch(mDocument, UPDATE_STYLE, PR_TRUE); diff --git a/mozilla/layout/style/nsCSSStyleSheet.h b/mozilla/layout/style/nsCSSStyleSheet.h index d7cf9c34b91..9179ceebf6c 100644 --- a/mozilla/layout/style/nsCSSStyleSheet.h +++ b/mozilla/layout/style/nsCSSStyleSheet.h @@ -186,6 +186,11 @@ protected: nsresult WillDirty(); void DidDirty(); + // Return success if the subject principal subsumes the principal of our + // inner, error otherwise. This will also succeed if the subject has + // UniversalBrowserWrite. + nsresult SubjectSubsumesInnerPrincipal() const; + protected: nsString mTitle; nsCOMPtr mMedia; diff --git a/mozilla/layout/style/nsCSSValue.cpp b/mozilla/layout/style/nsCSSValue.cpp index 9314a6327d3..e83e11b7476 100644 --- a/mozilla/layout/style/nsCSSValue.cpp +++ b/mozilla/layout/style/nsCSSValue.cpp @@ -435,9 +435,10 @@ nsCSSValue::Image::Image(nsIURI* aURI, nsStringBuffer* aString, MOZ_COUNT_CTOR(nsCSSValue::Image); if (mURI && - nsContentUtils::CanLoadImage(mURI, aDocument, aDocument)) { - nsContentUtils::LoadImage(mURI, aDocument, aReferrer, nsnull, - nsIRequest::LOAD_NORMAL, + nsContentUtils::CanLoadImage(mURI, aDocument, aDocument, + aOriginPrincipal)) { + nsContentUtils::LoadImage(mURI, aDocument, aOriginPrincipal, aReferrer, + nsnull, nsIRequest::LOAD_NORMAL, getter_AddRefs(mRequest)); } } diff --git a/mozilla/layout/xul/base/src/nsImageBoxFrame.cpp b/mozilla/layout/xul/base/src/nsImageBoxFrame.cpp index e6281591f70..03a7ee6b0d5 100644 --- a/mozilla/layout/xul/base/src/nsImageBoxFrame.cpp +++ b/mozilla/layout/xul/base/src/nsImageBoxFrame.cpp @@ -265,9 +265,10 @@ nsImageBoxFrame::UpdateImage() doc, baseURI); - if (uri && nsContentUtils::CanLoadImage(uri, mContent, doc)) { - nsContentUtils::LoadImage(uri, doc, doc->GetDocumentURI(), - mListener, mLoadFlags, + if (uri && nsContentUtils::CanLoadImage(uri, mContent, doc, + mContent->NodePrincipal())) { + nsContentUtils::LoadImage(uri, doc, mContent->NodePrincipal(), + doc->GetDocumentURI(), mListener, mLoadFlags, getter_AddRefs(mImageRequest)); } } else { diff --git a/mozilla/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp b/mozilla/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp index d8051226968..f5c36939348 100644 --- a/mozilla/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp +++ b/mozilla/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp @@ -2125,9 +2125,13 @@ nsTreeBodyFrame::GetImage(PRInt32 aRowIndex, nsTreeColumn* aCol, PRBool aUseCont if (!srcURI) return NS_ERROR_FAILURE; - if (nsContentUtils::CanLoadImage(srcURI, mContent, doc)) { + // XXXbz what's the origin principal for this stuff that comes from our + // view? I guess we should assume that it's the node's principal... + if (nsContentUtils::CanLoadImage(srcURI, mContent, doc, + mContent->NodePrincipal())) { nsresult rv = nsContentUtils::LoadImage(srcURI, doc, + mContent->NodePrincipal(), doc->GetDocumentURI(), imgDecoderObserver, nsIRequest::LOAD_NORMAL,