author | Christoph Kerschbaumer <ckerschb@christophkerschbaumer.com> |
Tue, 08 Nov 2016 07:23:12 +0100 | |
changeset 364466 | 57d473c3ca22cd2c6e7720ab796501ee68df4559 |
parent 364465 | 3e74d390dea4d3311b2eea00be094331dfe3f64f |
child 364467 | efc9b52a218f7ffd40ba346de74fd846a9059ceb |
push id | 6795 |
push user | jlund@mozilla.com |
push date | Mon, 23 Jan 2017 14:19:46 +0000 |
treeherder | mozilla-beta@76101b503191 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | bz |
bugs | 1308889 |
milestone | 52.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/caps/nsScriptSecurityManager.cpp +++ b/caps/nsScriptSecurityManager.cpp @@ -332,17 +332,21 @@ nsresult nsScriptSecurityManager::GetChannelResultPrincipal(nsIChannel* aChannel, nsIPrincipal** aPrincipal, bool aIgnoreSandboxing) { NS_PRECONDITION(aChannel, "Must have channel!"); // Check whether we have an nsILoadInfo that says what we should do. nsCOMPtr<nsILoadInfo> loadInfo = aChannel->GetLoadInfo(); if (loadInfo && loadInfo->GetForceInheritPrincipalOverruleOwner()) { - NS_ADDREF(*aPrincipal = loadInfo->PrincipalToInherit()); + nsCOMPtr<nsIPrincipal> principalToInherit = loadInfo->PrincipalToInherit(); + if (!principalToInherit) { + principalToInherit = loadInfo->TriggeringPrincipal(); + } + principalToInherit.forget(aPrincipal); return NS_OK; } nsCOMPtr<nsISupports> owner; aChannel->GetOwner(getter_AddRefs(owner)); if (owner) { CallQueryInterface(owner, aPrincipal); if (*aPrincipal) { @@ -372,29 +376,36 @@ nsScriptSecurityManager::GetChannelResul // Check if SEC_FORCE_INHERIT_PRINCIPAL was dropped because of // sandboxing: if (loadInfo->GetLoadingSandboxed() && loadInfo->GetForceInheritPrincipalDropped()) { forceInherit = true; } } if (forceInherit) { - NS_ADDREF(*aPrincipal = loadInfo->PrincipalToInherit()); + nsCOMPtr<nsIPrincipal> principalToInherit = loadInfo->PrincipalToInherit(); + if (!principalToInherit) { + principalToInherit = loadInfo->TriggeringPrincipal(); + } + principalToInherit.forget(aPrincipal); return NS_OK; } nsSecurityFlags securityFlags = loadInfo->GetSecurityMode(); if (securityFlags == nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_INHERITS || securityFlags == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS || securityFlags == nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS) { nsCOMPtr<nsIURI> uri; nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri)); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIPrincipal> principalToInherit = loadInfo->PrincipalToInherit(); + if (!principalToInherit) { + principalToInherit = loadInfo->TriggeringPrincipal(); + } bool inheritForAboutBlank = loadInfo->GetAboutBlankInherits(); if (nsContentUtils::ChannelShouldInheritPrincipal(principalToInherit, uri, inheritForAboutBlank, false)) { principalToInherit.forget(aPrincipal); return NS_OK;
--- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -1501,16 +1501,36 @@ nsDocShell::LoadURI(nsIURI* aURI, inheritPrincipal = nsContentUtils::LegacyIsCallerChromeOrNativeCode(); } if (aLoadFlags & LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL) { inheritPrincipal = false; principalToInherit = nsNullPrincipal::CreateWithInheritedAttributes(this); } + // If the triggeringPrincipal is not passed explicitly, we first try to create + // a principal from the referrer, since the referrer URI reflects the web origin + // that triggered the load. If there is no referrer URI, we fall back to using + // the SystemPrincipal. It's safe to assume that no provided triggeringPrincipal + // and no referrer simulate a load that was triggered by the system. + // It's important to note that this block of code needs to appear *after* the block + // where we munge the principalToInherit, because otherwise we would never enter + // code blocks checking if the principalToInherit is null and we will end up with + // a wrong inheritPrincipal flag. + if (!triggeringPrincipal) { + if (referrer) { + nsresult rv = CreatePrincipalFromReferrer(referrer, + getter_AddRefs(triggeringPrincipal)); + NS_ENSURE_SUCCESS(rv, rv); + } + else { + triggeringPrincipal = nsContentUtils::GetSystemPrincipal(); + } + } + uint32_t flags = 0; if (inheritPrincipal) { flags |= INTERNAL_LOAD_FLAGS_INHERIT_PRINCIPAL; } if (!sendReferrer) { flags |= INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER; @@ -5324,17 +5344,18 @@ nsDocShell::LoadErrorPage(nsIURI* aURI, errorPageUrl.AppendASCII(escapedDescription.get()); nsCOMPtr<nsIURI> errorPageURI; rv = NS_NewURI(getter_AddRefs(errorPageURI), errorPageUrl); NS_ENSURE_SUCCESS(rv, rv); return InternalLoad(errorPageURI, nullptr, false, nullptr, mozilla::net::RP_Default, - nullptr, nullptr, INTERNAL_LOAD_FLAGS_INHERIT_PRINCIPAL, EmptyString(), + nsContentUtils::GetSystemPrincipal(), nullptr, + INTERNAL_LOAD_FLAGS_NONE, EmptyString(), nullptr, NullString(), nullptr, nullptr, LOAD_ERROR_PAGE, nullptr, true, NullString(), this, nullptr, nullptr, nullptr); } NS_IMETHODIMP nsDocShell::Reload(uint32_t aReloadFlags) { @@ -5367,52 +5388,56 @@ nsDocShell::Reload(uint32_t aReloadFlags /* If you change this part of code, make sure bug 45297 does not re-occur */ if (mOSHE) { rv = LoadHistoryEntry(mOSHE, loadType); } else if (mLSHE) { // In case a reload happened before the current load is done rv = LoadHistoryEntry(mLSHE, loadType); } else { nsCOMPtr<nsIDocument> doc(GetDocument()); + if (!doc) { + return NS_OK; + } + // Do not inherit owner from document uint32_t flags = INTERNAL_LOAD_FLAGS_NONE; nsAutoString srcdoc; - nsIPrincipal* principal = nullptr; - nsAutoString contentTypeHint; nsCOMPtr<nsIURI> baseURI; nsCOMPtr<nsIURI> originalURI; bool loadReplace = false; - if (doc) { - principal = doc->NodePrincipal(); - doc->GetContentType(contentTypeHint); - - if (doc->IsSrcdocDocument()) { - doc->GetSrcdocData(srcdoc); - flags |= INTERNAL_LOAD_FLAGS_IS_SRCDOC; - baseURI = doc->GetBaseURI(); - } - nsCOMPtr<nsIChannel> chan = doc->GetChannel(); - if (chan) { - uint32_t loadFlags; - chan->GetLoadFlags(&loadFlags); - loadReplace = loadFlags & nsIChannel::LOAD_REPLACE; - nsCOMPtr<nsIHttpChannel> httpChan(do_QueryInterface(chan)); - if (httpChan) { - httpChan->GetOriginalURI(getter_AddRefs(originalURI)); - } - } - } + + nsIPrincipal* triggeringPrincipal = doc->NodePrincipal(); + nsAutoString contentTypeHint; + doc->GetContentType(contentTypeHint); + + if (doc->IsSrcdocDocument()) { + doc->GetSrcdocData(srcdoc); + flags |= INTERNAL_LOAD_FLAGS_IS_SRCDOC; + baseURI = doc->GetBaseURI(); + } + nsCOMPtr<nsIChannel> chan = doc->GetChannel(); + if (chan) { + uint32_t loadFlags; + chan->GetLoadFlags(&loadFlags); + loadReplace = loadFlags & nsIChannel::LOAD_REPLACE; + nsCOMPtr<nsIHttpChannel> httpChan(do_QueryInterface(chan)); + if (httpChan) { + httpChan->GetOriginalURI(getter_AddRefs(originalURI)); + } + } + + MOZ_ASSERT(triggeringPrincipal, "Need a valid triggeringPrincipal"); rv = InternalLoad(mCurrentURI, originalURI, loadReplace, mReferrerURI, mReferrerPolicy, - principal, - principal, + triggeringPrincipal, + triggeringPrincipal, flags, EmptyString(), // No window target NS_LossyConvertUTF16toASCII(contentTypeHint).get(), NullString(), // No forced download nullptr, // No post data nullptr, // No headers data loadType, // Load type nullptr, // No SHEntry @@ -9650,29 +9675,17 @@ nsDocShell::InternalLoad(nsIURI* aURI, nsISHEntry* aSHEntry, bool aFirstParty, const nsAString& aSrcdoc, nsIDocShell* aSourceDocShell, nsIURI* aBaseURI, nsIDocShell** aDocShell, nsIRequest** aRequest) { - // In most cases both principals (aTriggeringPrincipal and aPrincipalToInherit) - // are both null or both non-null. For the exceptional cases let's make sure that: - // * if aTriggeringPrincipal is null then either aPrincipalToInherit is null or - // it's a NullPrincipal - // * if aPrincipalToInherit is null then either aTriggeringPrincipal is null or - // it's a NullPrincipal or INTERNAL_LOAD_FLAGS_INHERIT_PRINCIPAL is set. - MOZ_ASSERT(aTriggeringPrincipal || - (!aPrincipalToInherit || - aPrincipalToInherit->GetIsNullPrincipal())); - MOZ_ASSERT(aPrincipalToInherit || - (!aTriggeringPrincipal || - aTriggeringPrincipal->GetIsNullPrincipal() || - (aFlags & INTERNAL_LOAD_FLAGS_INHERIT_PRINCIPAL))); + MOZ_ASSERT(aTriggeringPrincipal, "need a valid TriggeringPrincipal"); nsresult rv = NS_OK; mOriginalUriString.Truncate(); if (gDocShellLeakLog && MOZ_LOG_TEST(gDocShellLeakLog, LogLevel::Debug)) { PR_LogPrint("DOCSHELL %p InternalLoad %s\n", this, aURI ? aURI->GetSpecOrDefault().get() : ""); } @@ -9861,36 +9874,22 @@ nsDocShell::InternalLoad(nsIURI* aURI, // done by someone from chrome manually messing with our nsIWebNavigation // or by C++ setting document.location) don't get a funky principal. If // callers want something interesting to happen with the about:blank // principal in this case, they should pass aPrincipalToInherit in. // { bool inherits; // One more twist: Don't inherit the principal for external loads. - if (!principalToInherit && - NS_SUCCEEDED(nsContentUtils::URIInheritsSecurityContext(aURI, - &inherits)) && - inherits) { - if (aLoadType != LOAD_NORMAL_EXTERNAL && - (aFlags & INTERNAL_LOAD_FLAGS_INHERIT_PRINCIPAL)) { - principalToInherit = GetInheritedPrincipal(true); - } - - // In case we don't have a principalToInherit and the TriggeringPrincipal - // either already is a SystemPrincipal or would fall back to become - // a SystemPrincipal within the loadInfo then we should explicitly set - // the principalToInherit to a freshly created NullPrincipal. - if (!principalToInherit && - (nsContentUtils::IsSystemPrincipal(aTriggeringPrincipal) || - (!aTriggeringPrincipal && !aReferrer))) { - // We're going to default to inheriting our system triggering principal, - // more or less by accident. This doesn't seem like a good idea. - principalToInherit = nsNullPrincipal::CreateWithInheritedAttributes(this); - } + if (aLoadType != LOAD_NORMAL_EXTERNAL && !principalToInherit && + (aFlags & INTERNAL_LOAD_FLAGS_INHERIT_PRINCIPAL) && + NS_SUCCEEDED(nsContentUtils::URIInheritsSecurityContext(aURI, + &inherits)) && + inherits) { + principalToInherit = GetInheritedPrincipal(true); } } // Don't allow loads that would inherit our security context // if this document came from an unsafe channel. { bool willInherit; // This condition needs to match the one in @@ -10804,34 +10803,18 @@ nsDocShell::DoURILoad(nsIURI* aURI, // to load this resource. This docshell is scheduled for destruction // already, so bail out here. return NS_OK; } } // Getting the right triggeringPrincipal needs to be updated and is only // ready for use once bug 1182569 landed. Until then, we cannot rely on - // the triggeringPrincipal for TYPE_DOCUMENT loads. Please note that the - // triggeringPrincipal falls back to the systemPrincipal below. - nsCOMPtr<nsIPrincipal> triggeringPrincipal = aTriggeringPrincipal; - - // Make sure that we always get a non null triggeringPrincipal for - // loads of type TYPE_SUBDOCUMENT. - MOZ_ASSERT(aContentPolicyType != nsIContentPolicy::TYPE_SUBDOCUMENT || - triggeringPrincipal, "Need a valid triggeringPrincipal"); - - if (!triggeringPrincipal) { - if (aReferrerURI) { - rv = CreatePrincipalFromReferrer(aReferrerURI, - getter_AddRefs(triggeringPrincipal)); - NS_ENSURE_SUCCESS(rv, rv); - } else { - triggeringPrincipal = nsContentUtils::GetSystemPrincipal(); - } - } + // the triggeringPrincipal for TYPE_DOCUMENT loads. + MOZ_ASSERT(aTriggeringPrincipal, "Need a valid triggeringPrincipal"); bool isSandBoxed = mSandboxFlags & SANDBOXED_ORIGIN; // only inherit if we have a aPrincipalToInherit bool inherit = false; if (aPrincipalToInherit) { inherit = nsContentUtils::ChannelShouldInheritPrincipal( aPrincipalToInherit, @@ -10858,19 +10841,19 @@ nsDocShell::DoURILoad(nsIURI* aURI, securityFlags |= nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL; } if (isSandBoxed) { securityFlags |= nsILoadInfo::SEC_SANDBOXED; } nsCOMPtr<nsILoadInfo> loadInfo = (aContentPolicyType == nsIContentPolicy::TYPE_DOCUMENT) ? - new LoadInfo(loadingWindow, triggeringPrincipal, + new LoadInfo(loadingWindow, aTriggeringPrincipal, securityFlags) : - new LoadInfo(loadingPrincipal, triggeringPrincipal, loadingNode, + new LoadInfo(loadingPrincipal, aTriggeringPrincipal, loadingNode, securityFlags, aContentPolicyType); if (aPrincipalToInherit) { loadInfo->SetPrincipalToInherit(aPrincipalToInherit); } // We have to do this in case our OriginAttributes are different from the // OriginAttributes of the parent document. Or in case there isn't a @@ -12484,16 +12467,24 @@ nsDocShell::LoadHistoryEntry(nsISHEntry* if (isSrcdoc) { aEntry->GetSrcdocData(srcdoc); aEntry->GetBaseURI(getter_AddRefs(baseURI)); flags |= INTERNAL_LOAD_FLAGS_IS_SRCDOC; } else { srcdoc = NullString(); } + // If there is no triggeringPrincipal we can fall back to using the + // SystemPrincipal as the triggeringPrincipal for loading the history + // entry, since the history entry can only end up in history if security + // checks passed in the initial loading phase. + if (!triggeringPrincipal) { + triggeringPrincipal = nsContentUtils::GetSystemPrincipal(); + } + // Passing nullptr as aSourceDocShell gives the same behaviour as before // aSourceDocShell was introduced. According to spec we should be passing // the source browsing context that was used when the history entry was // first created. bug 947716 has been created to address this issue. rv = InternalLoad(uri, originalURI, loadReplace, referrerURI,
--- a/docshell/base/nsDocShell.h +++ b/docshell/base/nsDocShell.h @@ -343,24 +343,28 @@ protected: // Get the principal that we'll set on the channel if we're inheriting. If // aConsiderCurrentDocument is true, we try to use the current document if // at all possible. If that fails, we fall back on the parent document. // If that fails too, we force creation of a content viewer and use the // resulting principal. If aConsiderCurrentDocument is false, we just look // at the parent. nsIPrincipal* GetInheritedPrincipal(bool aConsiderCurrentDocument); - // Actually open a channel and perform a URI load. Note: whatever principal is - // passed to this function will be set on the channel. Callers who wish to - // not have an principal on the channel should just pass null. + // Actually open a channel and perform a URI load. Callers need to pass a + // non-null aTriggeringPrincipal which initiated the URI load. Please note + // that aTriggeringPrincipal will be used for performing security checks. + // If the argument aURI is provided by the web, then please do not pass a + // SystemPrincipal as the triggeringPrincipal. If principalToInherit is + // null, then no inheritance of any sort will happen and the load will + // get a principal based on the URI being loaded. // If aSrcdoc is not void, the load will be considered as a srcdoc load, // and the contents of aSrcdoc will be loaded instead of aURI. // aOriginalURI will be set as the originalURI on the channel that does the // load. If aOriginalURI is null, aURI will be set as the originalURI. - // If aLoadReplace is true, OLOAD_REPLACE flag will be set to the nsIChannel. + // If aLoadReplace is true, LOAD_REPLACE flag will be set to the nsIChannel. nsresult DoURILoad(nsIURI* aURI, nsIURI* aOriginalURI, bool aLoadReplace, nsIURI* aReferrer, bool aSendReferrer, uint32_t aReferrerPolicy, nsIPrincipal* aTriggeringPrincipal, nsIPrincipal* aPrincipalToInherit,
--- a/docshell/base/nsIDocShell.idl +++ b/docshell/base/nsIDocShell.idl @@ -127,45 +127,35 @@ interface nsIDocShell : nsIDocShellTreeI * @param aOriginalURI - The URI to set as the originalURI on the channel * that does the load. If null, aURI will be set as * the originalURI. * @param aLoadReplace - If set LOAD_REPLACE flag will be set on the * channel. aOriginalURI is null, this argument is * ignored. * @param aReferrer - Referring URI * @param aReferrerPolicy - Referrer policy - * @param aTriggeringPrincipal - Principal that initiated that load. If passing - * null for this argument, then internally a - * principal is created from aReferrer. If - * aReferrer is also null, then the - * triggeringPrincipal defaults to the - * SystemPrincipal. Please note that this is the - * principal that is used for security checks. If - * the argument aURI is provided by the web, then - * please pass an explicit triggeringPrincipal to - * avoid the fallback to SystemPrincipal and - * hence a potential security risk. - * If aTriggeringPrincipal is null then either - * aPrincipalToInherit is null or it's - * a NullPrincipal. - * @param aPrincipalToInherit - Principal to be inherited for that load. If - * passing null for this argument, then internally - * the triggeringPrincipal is also used for the - * principalToInherit. There are cases where those - * two principals need to be different though. - * E.g. the system might initiate a load for - * 'about:blank', hence SystemPrincipal is passed - * for aTriggeringPrincipal. But the principal to - * be inherited for that load should be a - * NullPrincipal and not the SystemPrincipal. - * In that case, please pass a non null - * principalToInherit. - * If aPrincipalToInherit is null then either - * aTriggeringPrincipal is null or - * INTERNAL_LOAD_FLAGS_INHERIT_PRINCIPAL is set. + * @param aTriggeringPrincipal - A non-null principal that initiated that load. + * Please note that this is the principal that is + * used for security checks. If the argument aURI + * is provided by the web, then please do not pass + * a SystemPrincipal as the triggeringPrincipal. + * @param aPrincipalToInherit - Principal to be inherited for that load. If this + * argument is null then principalToInherit is + * computed as follows: + * a) If INTERNAL_LOAD_FLAGS_INHERIT_PRINCIPAL, and + * aLoadType is not LOAD_NORMAL_EXTERNAL, and the + * URI would normally inherit a principal, then + * principalToInherit is set to the current + * document's principal, or parent document if + * there is not a current document. + * b) If principalToInherit is still null (e.g. if + * some of the conditions of (a) were not satisfied), + * then no inheritance of any sort will happen: the + * load will just get a principal based on the URI + * being loaded. * @param aFlags - Any of the load flags defined within above. * @param aStopActiveDoc - Flag indicating whether loading the current * document should be stopped. * @param aWindowTarget - Window target for the load. * @param aTypeHint - A hint as to the content-type of the resulting * data. May be null or empty if no hint. * @param aFileName - Non-null when the link should be downloaded as the given filename.
--- a/dom/base/nsObjectLoadingContent.cpp +++ b/dom/base/nsObjectLoadingContent.cpp @@ -2671,18 +2671,21 @@ nsObjectLoadingContent::OpenChannel() thisContent, securityFlags, contentPolicyType, group, // aLoadGroup shim, // aCallbacks nsIChannel::LOAD_CALL_CONTENT_SNIFFERS | nsIChannel::LOAD_CLASSIFY_URI | nsIChannel::LOAD_BYPASS_SERVICE_WORKER); - NS_ENSURE_SUCCESS(rv, rv); + if (inherit) { + nsCOMPtr<nsILoadInfo> loadinfo = chan->GetLoadInfo(); + loadinfo->SetPrincipalToInherit(thisContent->NodePrincipal()); + } // Referrer nsCOMPtr<nsIHttpChannel> httpChan(do_QueryInterface(chan)); if (httpChan) { httpChan->SetReferrerWithPolicy(doc->GetDocumentURI(), doc->GetReferrerPolicy()); // Set the initiator type
--- a/dom/html/nsHTMLDocument.cpp +++ b/dom/html/nsHTMLDocument.cpp @@ -2306,18 +2306,19 @@ nsHTMLDocument::CreateAndAddWyciwygChann // document.write() script to cache nsCOMPtr<nsIChannel> channel; // Create a wyciwyg Channel rv = NS_NewChannel(getter_AddRefs(channel), wcwgURI, NodePrincipal(), nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL, nsIContentPolicy::TYPE_OTHER); - NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr<nsILoadInfo> loadInfo = channel->GetLoadInfo(); + loadInfo->SetPrincipalToInherit(NodePrincipal()); mWyciwygChannel = do_QueryInterface(channel); mWyciwygChannel->SetSecurityInfo(mSecurityInfo); // Note: we want to treat this like a "previous document" hint so that, // e.g. a <meta> tag in the document.write content can override it. SetDocumentCharacterSetSource(kCharsetFromHintPrevDoc);
--- a/dom/jsurl/nsJSProtocolHandler.cpp +++ b/dom/jsurl/nsJSProtocolHandler.cpp @@ -156,16 +156,19 @@ nsresult nsJSThunk::EvaluateScript(nsICh nsCOMPtr<nsISupports> owner; aChannel->GetOwner(getter_AddRefs(owner)); nsCOMPtr<nsIPrincipal> principal = do_QueryInterface(owner); if (!principal) { nsCOMPtr<nsILoadInfo> loadInfo; aChannel->GetLoadInfo(getter_AddRefs(loadInfo)); if (loadInfo && loadInfo->GetForceInheritPrincipal()) { principal = loadInfo->PrincipalToInherit(); + if (!principal) { + principal = loadInfo->TriggeringPrincipal(); + } } else { // No execution without a principal! NS_ASSERTION(!owner, "Non-principal owner?"); NS_WARNING("No principal to execute JS with"); return NS_ERROR_DOM_RETVAL_UNDEFINED; } }
--- a/ipc/glue/BackgroundUtils.cpp +++ b/ipc/glue/BackgroundUtils.cpp @@ -221,19 +221,24 @@ LoadInfoToLoadInfoArgs(nsILoadInfo *aLoa NS_ENSURE_SUCCESS(rv, rv); loadingPrincipalInfo = loadingPrincipalInfoTemp; } PrincipalInfo triggeringPrincipalInfo; rv = PrincipalToPrincipalInfo(aLoadInfo->TriggeringPrincipal(), &triggeringPrincipalInfo); - PrincipalInfo principalToInheritInfo; - rv = PrincipalToPrincipalInfo(aLoadInfo->PrincipalToInherit(), - &principalToInheritInfo); + OptionalPrincipalInfo principalToInheritInfo = mozilla::void_t(); + if (aLoadInfo->PrincipalToInherit()) { + PrincipalInfo principalToInheritInfoTemp; + rv = PrincipalToPrincipalInfo(aLoadInfo->PrincipalToInherit(), + &principalToInheritInfoTemp); + NS_ENSURE_SUCCESS(rv, rv); + principalToInheritInfo = principalToInheritInfoTemp; + } nsTArray<PrincipalInfo> redirectChainIncludingInternalRedirects; for (const nsCOMPtr<nsIPrincipal>& principal : aLoadInfo->RedirectChainIncludingInternalRedirects()) { rv = PrincipalToPrincipalInfo(principal, redirectChainIncludingInternalRedirects.AppendElement()); NS_ENSURE_SUCCESS(rv, rv); } nsTArray<PrincipalInfo> redirectChain; @@ -292,19 +297,21 @@ LoadInfoArgsToLoadInfo(const OptionalLoa NS_ENSURE_SUCCESS(rv, rv); } NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIPrincipal> triggeringPrincipal = PrincipalInfoToPrincipal(loadInfoArgs.triggeringPrincipalInfo(), &rv); NS_ENSURE_SUCCESS(rv, rv); - nsCOMPtr<nsIPrincipal> principalToInherit = - PrincipalInfoToPrincipal(loadInfoArgs.principalToInheritInfo(), &rv); - NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr<nsIPrincipal> principalToInherit; + if (loadInfoArgs.principalToInheritInfo().type() != OptionalPrincipalInfo::Tvoid_t) { + principalToInherit = PrincipalInfoToPrincipal(loadInfoArgs.principalToInheritInfo(), &rv); + NS_ENSURE_SUCCESS(rv, rv); + } nsTArray<nsCOMPtr<nsIPrincipal>> redirectChainIncludingInternalRedirects; for (const PrincipalInfo& principalInfo : loadInfoArgs.redirectChainIncludingInternalRedirects()) { nsCOMPtr<nsIPrincipal> redirectedPrincipal = PrincipalInfoToPrincipal(principalInfo, &rv); NS_ENSURE_SUCCESS(rv, rv); redirectChainIncludingInternalRedirects.AppendElement(redirectedPrincipal.forget()); }
--- a/netwerk/base/LoadInfo.cpp +++ b/netwerk/base/LoadInfo.cpp @@ -40,17 +40,17 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadin nsIPrincipal* aTriggeringPrincipal, nsINode* aLoadingContext, nsSecurityFlags aSecurityFlags, nsContentPolicyType aContentPolicyType) : mLoadingPrincipal(aLoadingContext ? aLoadingContext->NodePrincipal() : aLoadingPrincipal) , mTriggeringPrincipal(aTriggeringPrincipal ? aTriggeringPrincipal : mLoadingPrincipal.get()) - , mPrincipalToInherit(mTriggeringPrincipal) + , mPrincipalToInherit(nullptr) , mLoadingContext(do_GetWeakReference(aLoadingContext)) , mSecurityFlags(aSecurityFlags) , mInternalContentPolicyType(aContentPolicyType) , mTainting(LoadTainting::Basic) , mUpgradeInsecureRequests(false) , mVerifySignedContent(false) , mEnforceSRI(false) , mForceInheritPrincipalDropped(false) @@ -63,17 +63,16 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadin , mIsThirdPartyContext(false) , mForcePreflight(false) , mIsPreflight(false) , mForceHSTSPriming(false) , mMixedContentWouldBlock(false) { MOZ_ASSERT(mLoadingPrincipal); MOZ_ASSERT(mTriggeringPrincipal); - MOZ_ASSERT(mPrincipalToInherit); #ifdef DEBUG // TYPE_DOCUMENT loads initiated by javascript tests will go through // nsIOService and use the wrong constructor. Don't enforce the // !TYPE_DOCUMENT check in those cases bool skipContentTypeCheck = false; skipContentTypeCheck = Preferences::GetBool("network.loadinfo.skip_type_assertion"); #endif @@ -214,17 +213,17 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadin * This constructor should only be used for TYPE_DOCUMENT loads, since they * have a null loadingNode and loadingPrincipal. */ LoadInfo::LoadInfo(nsPIDOMWindowOuter* aOuterWindow, nsIPrincipal* aTriggeringPrincipal, nsSecurityFlags aSecurityFlags) : mLoadingPrincipal(nullptr) , mTriggeringPrincipal(aTriggeringPrincipal) - , mPrincipalToInherit(mTriggeringPrincipal) + , mPrincipalToInherit(nullptr) , mSecurityFlags(aSecurityFlags) , mInternalContentPolicyType(nsIContentPolicy::TYPE_DOCUMENT) , mTainting(LoadTainting::Basic) , mUpgradeInsecureRequests(false) , mVerifySignedContent(false) , mEnforceSRI(false) , mForceInheritPrincipalDropped(false) , mInnerWindowID(0) @@ -238,17 +237,16 @@ LoadInfo::LoadInfo(nsPIDOMWindowOuter* a , mIsPreflight(false) , mForceHSTSPriming(false) , mMixedContentWouldBlock(false) { // Top-level loads are never third-party // Grab the information we can out of the window. MOZ_ASSERT(aOuterWindow); MOZ_ASSERT(mTriggeringPrincipal); - MOZ_ASSERT(mPrincipalToInherit); // if the load is sandboxed, we can not also inherit the principal if (mSecurityFlags & nsILoadInfo::SEC_SANDBOXED) { mSecurityFlags ^= nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL; mForceInheritPrincipalDropped = true; } // NB: Ignore the current inner window since we're navigating away from it. @@ -351,17 +349,16 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadin , mForcePreflight(aForcePreflight) , mIsPreflight(aIsPreflight) , mForceHSTSPriming (aForceHSTSPriming) , mMixedContentWouldBlock(aMixedContentWouldBlock) { // Only top level TYPE_DOCUMENT loads can have a null loadingPrincipal MOZ_ASSERT(mLoadingPrincipal || aContentPolicyType == nsIContentPolicy::TYPE_DOCUMENT); MOZ_ASSERT(mTriggeringPrincipal); - MOZ_ASSERT(mPrincipalToInherit); mRedirectChainIncludingInternalRedirects.SwapElements( aRedirectChainIncludingInternalRedirects); mRedirectChain.SwapElements(aRedirectChain); } LoadInfo::~LoadInfo() @@ -439,17 +436,17 @@ nsIPrincipal* LoadInfo::TriggeringPrincipal() { return mTriggeringPrincipal; } NS_IMETHODIMP LoadInfo::GetPrincipalToInherit(nsIPrincipal** aPrincipalToInherit) { - NS_ADDREF(*aPrincipalToInherit = mPrincipalToInherit); + NS_IF_ADDREF(*aPrincipalToInherit = mPrincipalToInherit); return NS_OK; } NS_IMETHODIMP LoadInfo::SetPrincipalToInherit(nsIPrincipal* aPrincipalToInherit) { MOZ_ASSERT(aPrincipalToInherit, "must be a valid principal to inherit"); mPrincipalToInherit = aPrincipalToInherit;
--- a/netwerk/base/nsILoadInfo.idl +++ b/netwerk/base/nsILoadInfo.idl @@ -269,19 +269,22 @@ interface nsILoadInfo : nsISupports /** * A C++-friendly version of triggeringPrincipal. */ [noscript, notxpcom, nostdcall, binaryname(TriggeringPrincipal)] nsIPrincipal binaryTriggeringPrincipal(); /** - * The principalToInherit is the principal that is used when the inherit flag - * is set. For loads that are not TYPE_DOCUMENT or TYPE_SUBDOCUMENT that - * principal is always identical to the triggeringPrincipal. + * For non-document loads the principalToInherit is always null. For + * loads of type TYPE_DOCUMENT or TYPE_SUBDOCUMENT the principalToInherit + * might be null. If it's non null, then this is the principal that is + * inherited if a principal needs to be inherited. If the principalToInherit + * is null but the inherit flag is set, then the triggeringPrincipal is + * the principal that is inherited. */ attribute nsIPrincipal principalToInherit; /** * A C++-friendly version of principalToInherit. */ [noscript, notxpcom, nostdcall, binaryname(PrincipalToInherit)] nsIPrincipal binaryPrincipalToInherit();
--- a/netwerk/ipc/NeckoChannelParams.ipdlh +++ b/netwerk/ipc/NeckoChannelParams.ipdlh @@ -27,17 +27,17 @@ namespace net { //----------------------------------------------------------------------------- // LoadInfo IPDL structs //----------------------------------------------------------------------------- struct LoadInfoArgs { OptionalPrincipalInfo requestingPrincipalInfo; PrincipalInfo triggeringPrincipalInfo; - PrincipalInfo principalToInheritInfo; + OptionalPrincipalInfo principalToInheritInfo; uint32_t securityFlags; uint32_t contentPolicyType; uint32_t tainting; bool upgradeInsecureRequests; bool verifySignedContent; bool enforceSRI; bool forceInheritPrincipalDropped; uint64_t innerWindowID;
--- a/toolkit/mozapps/extensions/amContentHandler.js +++ b/toolkit/mozapps/extensions/amContentHandler.js @@ -41,23 +41,28 @@ amContentHandler.prototype = { let callbacks = aRequest.notificationCallbacks ? aRequest.notificationCallbacks : aRequest.loadGroup.notificationCallbacks; if (callbacks) window = callbacks.getInterface(Ci.nsIDOMWindow); aRequest.cancel(Cr.NS_BINDING_ABORTED); + let principalToInherit = aRequest.loadInfo.principalToInherit; + if (!principalToInherit) { + principalToInherit = aRequest.loadInfo.triggeringPrincipal; + } + let installs = { uris: [uri.spec], hashes: [null], names: [null], icons: [null], mimetype: XPI_CONTENT_TYPE, - principalToInherit: aRequest.loadInfo.principalToInherit, + principalToInherit: principalToInherit, callbackID: -1 }; if (Services.appinfo.processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT) { // When running in the main process this might be a frame inside an // in-content UI page, walk up to find the first frame element in a chrome // privileged document let element = window.frameElement;