From 54c3583990b6713f2a276f97bb455b7977d8fc0d Mon Sep 17 00:00:00 2001 From: "aaronr%us.ibm.com" Date: Fri, 23 Jun 2006 17:10:43 +0000 Subject: [PATCH] [XForms] cannot submit with replace=instance more than one time part II. Bug 338451, patch by allan, r=doronr+bz, sr=sicking git-svn-id: svn://10.0.0.236/trunk@200695 18797224-902f-48f8-a5cc-f745e15eee43 --- .../xforms/nsIInstanceElementPrivate.idl | 4 +++ .../xforms/nsXFormsInstanceElement.cpp | 33 +++++++++++++++++++ .../xforms/nsXFormsInstanceElement.h | 13 ++++++++ .../xforms/nsXFormsSubmissionElement.cpp | 3 +- 4 files changed, 52 insertions(+), 1 deletion(-) diff --git a/mozilla/extensions/xforms/nsIInstanceElementPrivate.idl b/mozilla/extensions/xforms/nsIInstanceElementPrivate.idl index f0d7498a967..58a7d43e8c7 100644 --- a/mozilla/extensions/xforms/nsIInstanceElementPrivate.idl +++ b/mozilla/extensions/xforms/nsIInstanceElementPrivate.idl @@ -48,6 +48,10 @@ interface nsIInstanceElementPrivate : nsIXFormsNSInstanceElement { /** * Set instance document. + * + * WARNING: This must never be exposed to untrusted parties + * (ie. script). Because setting the instance document, we assume ownership + * over it security-wise! */ void setInstanceDocument(in nsIDOMDocument document); diff --git a/mozilla/extensions/xforms/nsXFormsInstanceElement.cpp b/mozilla/extensions/xforms/nsXFormsInstanceElement.cpp index 425569c5f2b..6d490e2223c 100644 --- a/mozilla/extensions/xforms/nsXFormsInstanceElement.cpp +++ b/mozilla/extensions/xforms/nsXFormsInstanceElement.cpp @@ -262,6 +262,14 @@ nsXFormsInstanceElement::OnStopRequest(nsIRequest *request, nsISupports *ctx, } } + // Replace the principal for the loaded document + nsCOMPtr iDoc(do_QueryInterface(mDocument)); + nsresult rv = ReplacePrincipal(iDoc); + if (NS_FAILED(rv)) { + SetInstanceDocument(nsnull); + return rv; + } + nsCOMPtr model = GetModel(); if (model) { model->InstanceLoadFinished(succeeded); @@ -271,6 +279,22 @@ nsXFormsInstanceElement::OnStopRequest(nsIRequest *request, nsISupports *ctx, return NS_OK; } +nsresult +nsXFormsInstanceElement::ReplacePrincipal(nsIDocument *aDocument) +{ + if (!aDocument || !mElement) + return NS_ERROR_FAILURE; + + // Set Principal + nsCOMPtr domDoc; + mElement->GetOwnerDocument(getter_AddRefs(domDoc)); + nsCOMPtr fromDoc(do_QueryInterface(domDoc)); + NS_ENSURE_STATE(fromDoc); + aDocument->SetPrincipal(fromDoc->NodePrincipal()); + + return NS_OK; +} + // nsIXFormsNSInstanceElement NS_IMETHODIMP @@ -303,6 +327,15 @@ nsXFormsInstanceElement::SetInstanceDocument(nsIDOMDocument *aDocument) NS_ENSURE_STATE(owner); rv = doc->SetProperty(nsXFormsAtoms::instanceDocumentOwner, owner); NS_ENSURE_SUCCESS(rv, rv); + + // Replace the principal of the instance document so it is the same as for + // the owning form. Why is this not a security breach? Because we handle + // our own whitelist of domains that we trust (see + // nsXFormsUtils::CheckSameOrigin()), and if we have gotten this far + // (ie. loaded the document) the user has trusted obviously trusted the + // source. See also https://bugzilla.mozilla.org/show_bug.cgi?id=338451 + rv = ReplacePrincipal(doc); + NS_ENSURE_SUCCESS(rv, rv); } return NS_OK; diff --git a/mozilla/extensions/xforms/nsXFormsInstanceElement.h b/mozilla/extensions/xforms/nsXFormsInstanceElement.h index a37f32ef2ef..d8ebd21239f 100644 --- a/mozilla/extensions/xforms/nsXFormsInstanceElement.h +++ b/mozilla/extensions/xforms/nsXFormsInstanceElement.h @@ -49,6 +49,7 @@ #include "nsIChannelEventSink.h" #include "nsIInterfaceRequestor.h" +class nsIDocument; class nsIDOMElement; /** @@ -88,6 +89,18 @@ private: NS_HIDDEN_(nsresult) CreateInstanceDocument(const nsAString &aQualifiedName); NS_HIDDEN_(already_AddRefed) GetModel(); + /** + * Replace principal for document to be the same as for the owning document. + * + * WARNING: This could lead to a security breach, and should be used with + * extreme care! + * + * @see https://bugzilla.mozilla.org/show_bug.cgi?id=338451 + * + * @param aDoc The document to replace principal for + */ + nsresult ReplacePrincipal(nsIDocument *aDoc); + nsCOMPtr mDocument; nsCOMPtr mOriginalDocument; nsIDOMElement *mElement; diff --git a/mozilla/extensions/xforms/nsXFormsSubmissionElement.cpp b/mozilla/extensions/xforms/nsXFormsSubmissionElement.cpp index 5f191eca8d8..d10d56866db 100644 --- a/mozilla/extensions/xforms/nsXFormsSubmissionElement.cpp +++ b/mozilla/extensions/xforms/nsXFormsSubmissionElement.cpp @@ -495,7 +495,8 @@ nsXFormsSubmissionElement::LoadReplaceInstance(nsIChannel *channel) mPipeIn->Available(&contentLength); // set the base uri so that the document can get the correct security - // principal + // principal (this has to be here to work on 1.8.0) + // @see https://bugzilla.mozilla.org/show_bug.cgi?id=338451 nsCOMPtr uri; nsresult rv = channel->GetURI(getter_AddRefs(uri)); NS_ENSURE_SUCCESS(rv, rv);