[tbb-commits] [tor-browser] 07/14: Bug 1658869 - Propagate the InterceptedHttpChannel information to fetch's channel casued by FetchEvent.request. r=dom-worker-reviewers, dragana, jesup, a=dmeehan
gitolite role
git at cupani.torproject.org
Thu Nov 17 14:03:46 UTC 2022
This is an automated email from the git hooks/post-receive script.
richard pushed a commit to branch tor-browser-91.13.0esr-11.5-1
in repository tor-browser.
commit c2811c81a2c3f2f846f4540039bc326d0a519400
Author: Eden Chuang <echuang at mozilla.com>
AuthorDate: Tue Oct 11 12:09:16 2022 +0000
Bug 1658869 - Propagate the InterceptedHttpChannel information to fetch's channel casued by FetchEvent.request. r=dom-worker-reviewers,dragana,jesup, a=dmeehan
When a network load needs to be intercepted by ServiceWorker, we extract the Request from the InterceptedHttpChannel, and propagate the Request through FetchEvent.request.
However, some needed information is not extracted or is modified during the Request propagation, so getting the wrong result when using the Request to fetch resources in the ServiceWorker script.
Differential Revision: https://phabricator.services.mozilla.com/D145969
---
dom/fetch/Fetch.cpp | 21 +++++++
dom/fetch/FetchDriver.cpp | 30 ++++++++++
dom/fetch/FetchTypes.ipdlh | 5 ++
dom/fetch/InternalRequest.cpp | 32 ++++++++++-
dom/fetch/InternalRequest.h | 54 +++++++++++++++++-
dom/serviceworkers/ServiceWorkerPrivateImpl.cpp | 27 ++++++++-
ipc/glue/BackgroundUtils.cpp | 59 +++++++++++++++++++-
netwerk/base/InterceptionInfo.cpp | 63 +++++++++++++++++++++
netwerk/base/InterceptionInfo.h | 44 +++++++++++++++
netwerk/base/LoadInfo.cpp | 16 ++++--
netwerk/base/LoadInfo.h | 5 +-
netwerk/base/TRRLoadInfo.cpp | 3 +
netwerk/base/moz.build | 3 +
netwerk/base/nsIInterceptionInfo.idl | 73 +++++++++++++++++++++++++
netwerk/base/nsILoadInfo.idl | 15 +++++
netwerk/cookie/CookieCommons.cpp | 68 +++++++++++++++++------
netwerk/ipc/NeckoChannelParams.ipdlh | 9 +++
17 files changed, 497 insertions(+), 30 deletions(-)
diff --git a/dom/fetch/Fetch.cpp b/dom/fetch/Fetch.cpp
index b22bd8f66300..2cff924eb59f 100644
--- a/dom/fetch/Fetch.cpp
+++ b/dom/fetch/Fetch.cpp
@@ -510,6 +510,27 @@ already_AddRefed<Promise> FetchRequest(nsIGlobalObject* aGlobal,
}
SafeRefPtr<InternalRequest> r = request->GetInternalRequest();
+
+ // Restore information of InterceptedHttpChannel if they are passed with the
+ // Request. Since Request::Constructor would not copy these members.
+ if (aInput.IsRequest()) {
+ RefPtr<Request> inputReq = &aInput.GetAsRequest();
+ SafeRefPtr<InternalRequest> inputInReq = inputReq->GetInternalRequest();
+ if (inputInReq->GetInterceptionTriggeringPrincipalInfo()) {
+ r->SetInterceptionContentPolicyType(
+ inputInReq->InterceptionContentPolicyType());
+ r->SetInterceptionTriggeringPrincipalInfo(
+ MakeUnique<mozilla::ipc::PrincipalInfo>(
+ *(inputInReq->GetInterceptionTriggeringPrincipalInfo().get())));
+ if (!inputInReq->InterceptionRedirectChain().IsEmpty()) {
+ r->SetInterceptionRedirectChain(
+ inputInReq->InterceptionRedirectChain());
+ }
+ r->SetInterceptionFromThirdParty(
+ inputInReq->InterceptionFromThirdParty());
+ }
+ }
+
RefPtr<AbortSignalImpl> signalImpl = request->GetSignalImpl();
if (signalImpl && signalImpl->Aborted()) {
diff --git a/dom/fetch/FetchDriver.cpp b/dom/fetch/FetchDriver.cpp
index 4da3e0faa2f0..ca3f75b14f87 100644
--- a/dom/fetch/FetchDriver.cpp
+++ b/dom/fetch/FetchDriver.cpp
@@ -12,6 +12,7 @@
#include "nsICookieJarSettings.h"
#include "nsIFile.h"
#include "nsIInputStream.h"
+#include "nsIInterceptionInfo.h"
#include "nsIOutputStream.h"
#include "nsIFileChannel.h"
#include "nsIHttpChannel.h"
@@ -21,6 +22,7 @@
#include "nsIUploadChannel2.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsIPipe.h"
+#include "nsIRedirectHistoryEntry.h"
#include "nsContentPolicyUtils.h"
#include "nsDataHandler.h"
@@ -37,6 +39,7 @@
#include "mozilla/dom/UserActivation.h"
#include "mozilla/dom/WorkerCommon.h"
#include "mozilla/PreloaderBase.h"
+#include "mozilla/net/InterceptionInfo.h"
#include "mozilla/net/NeckoChannelParams.h"
#include "mozilla/ipc/PBackgroundSharedTypes.h"
#include "mozilla/StaticPrefs_browser.h"
@@ -647,6 +650,33 @@ nsresult FetchDriver::HttpFetch(
NS_ENSURE_SUCCESS(rv, rv);
}
+ // If the fetch is created by FetchEvent.request or NavigationPreload request,
+ // corresponding InterceptedHttpChannel information need to propagte to the
+ // channel of the fetch.
+ if (mRequest->GetInterceptionTriggeringPrincipalInfo()) {
+ auto principalOrErr = mozilla::ipc::PrincipalInfoToPrincipal(
+ *(mRequest->GetInterceptionTriggeringPrincipalInfo().get()));
+ if (!principalOrErr.isErr()) {
+ nsCOMPtr<nsIPrincipal> principal = principalOrErr.unwrap();
+
+ nsTArray<nsCOMPtr<nsIRedirectHistoryEntry>> redirectChain;
+ if (!mRequest->InterceptionRedirectChain().IsEmpty()) {
+ for (const RedirectHistoryEntryInfo& entryInfo :
+ mRequest->InterceptionRedirectChain()) {
+ nsCOMPtr<nsIRedirectHistoryEntry> entry =
+ mozilla::ipc::RHEntryInfoToRHEntry(entryInfo);
+ redirectChain.AppendElement(entry);
+ }
+ }
+
+ nsCOMPtr<nsILoadInfo> loadInfo = chan->LoadInfo();
+ MOZ_ASSERT(loadInfo);
+ loadInfo->SetInterceptionInfo(new mozilla::net::InterceptionInfo(
+ principal, mRequest->InterceptionContentPolicyType(), redirectChain,
+ mRequest->InterceptionFromThirdParty()));
+ }
+ }
+
if (mDocument && mDocument->GetEmbedderElement() &&
mDocument->GetEmbedderElement()->IsAnyOfHTMLElements(nsGkAtoms::object,
nsGkAtoms::embed)) {
diff --git a/dom/fetch/FetchTypes.ipdlh b/dom/fetch/FetchTypes.ipdlh
index a01c5154e5b9..cb9449331baf 100644
--- a/dom/fetch/FetchTypes.ipdlh
+++ b/dom/fetch/FetchTypes.ipdlh
@@ -7,6 +7,7 @@ include ChannelInfo;
include PBackgroundSharedTypes;
include protocol PRemoteLazyInputStream;
+include NeckoChannelParams;
include "mozilla/dom/FetchIPCTypes.h";
@@ -64,6 +65,10 @@ struct IPCInternalRequest {
nsString integrity;
nsCString fragment;
PrincipalInfo? principalInfo;
+ PrincipalInfo? interceptionTriggeringPrincipalInfo;
+ uint32_t interceptionContentPolicyType;
+ RedirectHistoryEntryInfo[] interceptionRedirectChain;
+ bool interceptionFromThirdParty;
};
struct IPCInternalResponse {
diff --git a/dom/fetch/InternalRequest.cpp b/dom/fetch/InternalRequest.cpp
index 089465a53320..c7bf24665b92 100644
--- a/dom/fetch/InternalRequest.cpp
+++ b/dom/fetch/InternalRequest.cpp
@@ -137,8 +137,17 @@ InternalRequest::InternalRequest(const InternalRequest& aOther,
mSynchronous(aOther.mSynchronous),
mUnsafeRequest(aOther.mUnsafeRequest),
mUseURLCredentials(aOther.mUseURLCredentials),
- mContentPolicyTypeOverridden(aOther.mContentPolicyTypeOverridden) {
+ mContentPolicyTypeOverridden(aOther.mContentPolicyTypeOverridden),
+ mInterceptionContentPolicyType(aOther.mInterceptionContentPolicyType),
+ mInterceptionRedirectChain(aOther.mInterceptionRedirectChain),
+ mInterceptionFromThirdParty(aOther.mInterceptionFromThirdParty) {
// NOTE: does not copy body stream... use the fallible Clone() for that
+
+ if (aOther.GetInterceptionTriggeringPrincipalInfo()) {
+ mInterceptionTriggeringPrincipalInfo =
+ MakeUnique<mozilla::ipc::PrincipalInfo>(
+ *(aOther.GetInterceptionTriggeringPrincipalInfo().get()));
+ }
}
InternalRequest::InternalRequest(const IPCInternalRequest& aIPCRequest)
@@ -157,12 +166,22 @@ InternalRequest::InternalRequest(const IPCInternalRequest& aIPCRequest)
mCacheMode(aIPCRequest.cacheMode()),
mRedirectMode(aIPCRequest.requestRedirect()),
mIntegrity(aIPCRequest.integrity()),
- mFragment(aIPCRequest.fragment()) {
+ mFragment(aIPCRequest.fragment()),
+ mInterceptionContentPolicyType(static_cast<nsContentPolicyType>(
+ aIPCRequest.interceptionContentPolicyType())),
+ mInterceptionRedirectChain(aIPCRequest.interceptionRedirectChain()),
+ mInterceptionFromThirdParty(aIPCRequest.interceptionFromThirdParty()) {
if (aIPCRequest.principalInfo()) {
mPrincipalInfo = MakeUnique<mozilla::ipc::PrincipalInfo>(
aIPCRequest.principalInfo().ref());
}
+ if (aIPCRequest.interceptionTriggeringPrincipalInfo()) {
+ mInterceptionTriggeringPrincipalInfo =
+ MakeUnique<mozilla::ipc::PrincipalInfo>(
+ aIPCRequest.interceptionTriggeringPrincipalInfo().ref());
+ }
+
const Maybe<BodyStreamVariant>& body = aIPCRequest.body();
// This constructor is (currently) only used for parent -> child communication
@@ -188,6 +207,11 @@ void InternalRequest::OverrideContentPolicyType(
mContentPolicyTypeOverridden = true;
}
+void InternalRequest::SetInterceptionContentPolicyType(
+ nsContentPolicyType aContentPolicyType) {
+ mInterceptionContentPolicyType = aContentPolicyType;
+}
+
/* static */
RequestDestination InternalRequest::MapContentPolicyTypeToRequestDestination(
nsContentPolicyType aContentPolicyType) {
@@ -397,4 +421,8 @@ void InternalRequest::SetPrincipalInfo(
mPrincipalInfo = std::move(aPrincipalInfo);
}
+void InternalRequest::SetInterceptionTriggeringPrincipalInfo(
+ UniquePtr<mozilla::ipc::PrincipalInfo> aPrincipalInfo) {
+ mInterceptionTriggeringPrincipalInfo = std::move(aPrincipalInfo);
+}
} // namespace mozilla::dom
diff --git a/dom/fetch/InternalRequest.h b/dom/fetch/InternalRequest.h
index a526089fe2e7..eed09227c6e0 100644
--- a/dom/fetch/InternalRequest.h
+++ b/dom/fetch/InternalRequest.h
@@ -17,12 +17,15 @@
#include "nsIChannelEventSink.h"
#include "nsIInputStream.h"
#include "nsISupportsImpl.h"
+#include "mozilla/net/NeckoChannelParams.h"
#ifdef DEBUG
# include "nsIURLParser.h"
# include "nsNetCID.h"
# include "nsServiceManagerUtils.h"
#endif
+using mozilla::net::RedirectHistoryEntryInfo;
+
namespace mozilla {
namespace ipc {
@@ -322,7 +325,6 @@ class InternalRequest final : public AtomicSafeRefCounted<InternalRequest> {
// Takes ownership of the principal info.
void SetPrincipalInfo(UniquePtr<mozilla::ipc::PrincipalInfo> aPrincipalInfo);
-
const UniquePtr<mozilla::ipc::PrincipalInfo>& GetPrincipalInfo() const {
return mPrincipalInfo;
}
@@ -347,6 +349,36 @@ class InternalRequest final : public AtomicSafeRefCounted<InternalRequest> {
return mEmbedderPolicy;
}
+ void SetInterceptionTriggeringPrincipalInfo(
+ UniquePtr<mozilla::ipc::PrincipalInfo> aPrincipalInfo);
+
+ const UniquePtr<mozilla::ipc::PrincipalInfo>&
+ GetInterceptionTriggeringPrincipalInfo() const {
+ return mInterceptionTriggeringPrincipalInfo;
+ }
+
+ nsContentPolicyType InterceptionContentPolicyType() const {
+ return mInterceptionContentPolicyType;
+ }
+ void SetInterceptionContentPolicyType(nsContentPolicyType aContentPolicyType);
+
+ const nsTArray<RedirectHistoryEntryInfo>& InterceptionRedirectChain() const {
+ return mInterceptionRedirectChain;
+ }
+
+ void SetInterceptionRedirectChain(
+ const nsTArray<RedirectHistoryEntryInfo>& aRedirectChain) {
+ mInterceptionRedirectChain = aRedirectChain;
+ }
+
+ const bool& InterceptionFromThirdParty() const {
+ return mInterceptionFromThirdParty;
+ }
+
+ void SetInterceptionFromThirdParty(bool aFromThirdParty) {
+ mInterceptionFromThirdParty = aFromThirdParty;
+ }
+
private:
struct ConstructorGuard {};
@@ -420,6 +452,26 @@ class InternalRequest final : public AtomicSafeRefCounted<InternalRequest> {
nsILoadInfo::EMBEDDER_POLICY_NULL;
UniquePtr<mozilla::ipc::PrincipalInfo> mPrincipalInfo;
+
+ // Following members are specific for the FetchEvent.request or
+ // NavigationPreload request which is extracted from the
+ // InterceptedHttpChannel.
+ // Notice that these members would not be copied when calling
+ // InternalRequest::GetRequestConstructorCopy() since these information should
+ // not be propagated when copying the Request in ServiceWorker script.
+
+ // This is the trigging principalInfo of the InterceptedHttpChannel.
+ UniquePtr<mozilla::ipc::PrincipalInfo> mInterceptionTriggeringPrincipalInfo;
+
+ // This is the contentPolicyType of the InterceptedHttpChannel.
+ nsContentPolicyType mInterceptionContentPolicyType{
+ nsIContentPolicy::TYPE_INVALID};
+
+ // This is the redirect history of the InterceptedHttpChannel.
+ CopyableTArray<RedirectHistoryEntryInfo> mInterceptionRedirectChain;
+
+ // This indicates that the InterceptedHttpChannel is a third party channel.
+ bool mInterceptionFromThirdParty{false};
};
} // namespace dom
diff --git a/dom/serviceworkers/ServiceWorkerPrivateImpl.cpp b/dom/serviceworkers/ServiceWorkerPrivateImpl.cpp
index 17bf3fcb2a1a..8894a33ccd49 100644
--- a/dom/serviceworkers/ServiceWorkerPrivateImpl.cpp
+++ b/dom/serviceworkers/ServiceWorkerPrivateImpl.cpp
@@ -19,6 +19,7 @@
#include "nsIHttpHeaderVisitor.h"
#include "nsINetworkInterceptController.h"
#include "nsIObserverService.h"
+#include "nsIRedirectHistoryEntry.h"
#include "nsIScriptError.h"
#include "nsIURI.h"
#include "nsIUploadChannel2.h"
@@ -29,6 +30,7 @@
#include "ServiceWorkerCloneData.h"
#include "ServiceWorkerManager.h"
#include "ServiceWorkerRegistrationInfo.h"
+#include "mozIThirdPartyUtil.h"
#include "mozilla/Assertions.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/ipc/PBackgroundChild.h"
@@ -748,11 +750,33 @@ Result<IPCInternalRequest, nsresult> GetIPCInternalRequest(
}
Maybe<PrincipalInfo> principalInfo;
+ Maybe<PrincipalInfo> interceptionPrincipalInfo;
if (loadInfo->TriggeringPrincipal()) {
principalInfo.emplace();
+ interceptionPrincipalInfo.emplace();
MOZ_ALWAYS_SUCCEEDS(PrincipalToPrincipalInfo(
loadInfo->TriggeringPrincipal(), principalInfo.ptr()));
+ MOZ_ALWAYS_SUCCEEDS(PrincipalToPrincipalInfo(
+ loadInfo->TriggeringPrincipal(), interceptionPrincipalInfo.ptr()));
+ }
+
+ nsTArray<RedirectHistoryEntryInfo> redirectChain;
+ for (const nsCOMPtr<nsIRedirectHistoryEntry>& redirectEntry :
+ loadInfo->RedirectChain()) {
+ RedirectHistoryEntryInfo* entry = redirectChain.AppendElement();
+ MOZ_ALWAYS_SUCCEEDS(RHEntryToRHEntryInfo(redirectEntry, entry));
+ }
+
+ bool isThirdPartyChannel;
+ // ThirdPartyUtil* thirdPartyUtil = ThirdPartyUtil::GetInstance();
+ nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil =
+ do_GetService(THIRDPARTYUTIL_CONTRACTID);
+ if (thirdPartyUtil) {
+ nsCOMPtr<nsIURI> uri;
+ MOZ_TRY(underlyingChannel->GetURI(getter_AddRefs(uri)));
+ MOZ_TRY(thirdPartyUtil->IsThirdPartyChannel(underlyingChannel, uri,
+ &isThirdPartyChannel));
}
// Note: all the arguments are copied rather than moved, which would be more
@@ -761,7 +785,8 @@ Result<IPCInternalRequest, nsresult> GetIPCInternalRequest(
method, {spec}, ipcHeadersGuard, ipcHeaders, Nothing(), -1,
alternativeDataType, contentPolicyType, referrer, referrerPolicy,
requestMode, requestCredentials, cacheMode, requestRedirect, integrity,
- fragment, principalInfo);
+ fragment, principalInfo, interceptionPrincipalInfo, contentPolicyType,
+ redirectChain, isThirdPartyChannel);
}
nsresult MaybeStoreStreamForBackgroundThread(nsIInterceptedChannel* aChannel,
diff --git a/ipc/glue/BackgroundUtils.cpp b/ipc/glue/BackgroundUtils.cpp
index f6ede009be9d..25e196e53991 100644
--- a/ipc/glue/BackgroundUtils.cpp
+++ b/ipc/glue/BackgroundUtils.cpp
@@ -14,6 +14,7 @@
#include "mozilla/ipc/PBackgroundSharedTypes.h"
#include "mozilla/ipc/URIUtils.h"
#include "mozilla/net/CookieJarSettings.h"
+#include "mozilla/net/InterceptionInfo.h"
#include "mozilla/net/NeckoChannelParams.h"
#include "ExpandedPrincipal.h"
#include "nsIScriptSecurityManager.h"
@@ -501,6 +502,29 @@ nsresult LoadInfoToLoadInfoArgs(nsILoadInfo* aLoadInfo,
nsCOMPtr<nsIURI> unstrippedURI;
Unused << aLoadInfo->GetUnstrippedURI(getter_AddRefs(unstrippedURI));
+ Maybe<InterceptionInfoArg> interceptionInfoArg;
+ nsIInterceptionInfo* interceptionInfo = aLoadInfo->InterceptionInfo();
+ if (interceptionInfo) {
+ Maybe<PrincipalInfo> triggeringPrincipalInfo;
+ if (interceptionInfo->TriggeringPrincipal()) {
+ triggeringPrincipalInfo.emplace();
+ rv = PrincipalToPrincipalInfo(interceptionInfo->TriggeringPrincipal(),
+ triggeringPrincipalInfo.ptr());
+ }
+
+ nsTArray<RedirectHistoryEntryInfo> redirectChain;
+ for (const nsCOMPtr<nsIRedirectHistoryEntry>& redirectEntry :
+ interceptionInfo->RedirectChain()) {
+ RedirectHistoryEntryInfo* entry = redirectChain.AppendElement();
+ rv = RHEntryToRHEntryInfo(redirectEntry, entry);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ interceptionInfoArg = Some(InterceptionInfoArg(
+ triggeringPrincipalInfo, interceptionInfo->ContentPolicyType(),
+ redirectChain, interceptionInfo->FromThirdParty()));
+ }
+
*aOptionalLoadInfoArgs = Some(LoadInfoArgs(
loadingPrincipalInfo, triggeringPrincipalInfo, principalToInheritInfo,
sandboxedLoadingPrincipalInfo, topLevelPrincipalInfo,
@@ -543,7 +567,8 @@ nsresult LoadInfoToLoadInfoArgs(nsILoadInfo* aLoadInfo,
aLoadInfo->GetIsFromObjectOrEmbed(), cookieJarSettingsArgs,
aLoadInfo->GetRequestBlockingReason(), maybeCspToInheritInfo,
aLoadInfo->GetHasStoragePermission(), aLoadInfo->GetIsMetaRefresh(),
- aLoadInfo->GetLoadingEmbedderPolicy(), unstrippedURI));
+ aLoadInfo->GetLoadingEmbedderPolicy(), unstrippedURI,
+ interceptionInfoArg));
return NS_OK;
}
@@ -691,7 +716,6 @@ nsresult LoadInfoArgsToLoadInfo(
NS_ENSURE_SUCCESS(rv, rv);
redirectChain.AppendElement(redirectHistoryEntry.forget());
}
-
nsTArray<nsCOMPtr<nsIPrincipal>> ancestorPrincipals;
nsTArray<uint64_t> ancestorBrowsingContextIDs;
if (XRE_IsParentProcess() &&
@@ -760,6 +784,34 @@ nsresult LoadInfoArgsToLoadInfo(
loadingContext = frameBrowsingContext->GetEmbedderElement();
}
+ nsCOMPtr<nsIInterceptionInfo> interceptionInfo;
+ if (loadInfoArgs.interceptionInfo().isSome()) {
+ const InterceptionInfoArg& interceptionInfoArg =
+ loadInfoArgs.interceptionInfo().ref();
+ nsCOMPtr<nsIPrincipal> triggeringPrincipal;
+ if (interceptionInfoArg.triggeringPrincipalInfo().isSome()) {
+ auto triggeringPrincipalOrErr = PrincipalInfoToPrincipal(
+ interceptionInfoArg.triggeringPrincipalInfo().ref());
+ if (NS_WARN_IF(triggeringPrincipalOrErr.isErr())) {
+ return triggeringPrincipalOrErr.unwrapErr();
+ }
+ triggeringPrincipal = triggeringPrincipalOrErr.unwrap();
+ }
+
+ RedirectHistoryArray redirectChain;
+ for (const RedirectHistoryEntryInfo& entryInfo :
+ interceptionInfoArg.redirectChain()) {
+ nsCOMPtr<nsIRedirectHistoryEntry> redirectHistoryEntry =
+ RHEntryInfoToRHEntry(entryInfo);
+ NS_ENSURE_SUCCESS(rv, rv);
+ redirectChain.AppendElement(redirectHistoryEntry.forget());
+ }
+
+ interceptionInfo = new InterceptionInfo(
+ triggeringPrincipal, interceptionInfoArg.contentPolicyType(),
+ redirectChain, interceptionInfoArg.fromThirdParty());
+ }
+
RefPtr<mozilla::net::LoadInfo> loadInfo = new mozilla::net::LoadInfo(
loadingPrincipal, triggeringPrincipal, principalToInherit,
sandboxedLoadingPrincipal, topLevelPrincipal,
@@ -800,7 +852,8 @@ nsresult LoadInfoArgsToLoadInfo(
loadInfoArgs.isInDevToolsContext(), loadInfoArgs.parserCreatedScript(),
loadInfoArgs.hasStoragePermission(), loadInfoArgs.isMetaRefresh(),
loadInfoArgs.requestBlockingReason(), loadingContext,
- loadInfoArgs.loadingEmbedderPolicy(), loadInfoArgs.unstrippedURI());
+ loadInfoArgs.loadingEmbedderPolicy(), loadInfoArgs.unstrippedURI(),
+ interceptionInfo);
if (loadInfoArgs.isFromProcessingFrameAttributes()) {
loadInfo->SetIsFromProcessingFrameAttributes();
diff --git a/netwerk/base/InterceptionInfo.cpp b/netwerk/base/InterceptionInfo.cpp
new file mode 100644
index 000000000000..977ec02e4700
--- /dev/null
+++ b/netwerk/base/InterceptionInfo.cpp
@@ -0,0 +1,63 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozilla/net/InterceptionInfo.h"
+#include "nsContentUtils.h"
+
+namespace mozilla::net {
+
+NS_IMPL_ISUPPORTS(InterceptionInfo, nsIInterceptionInfo)
+
+InterceptionInfo::InterceptionInfo(nsIPrincipal* aTriggeringPrincipal,
+ nsContentPolicyType aContentPolicyType,
+ const RedirectHistoryArray& aRedirectChain,
+ bool aFromThirdParty)
+ : mTriggeringPrincipal(aTriggeringPrincipal),
+ mContentPolicyType(aContentPolicyType),
+ mFromThirdParty(aFromThirdParty) {
+ SetRedirectChain(aRedirectChain);
+}
+
+nsIPrincipal* InterceptionInfo::TriggeringPrincipal() {
+ return mTriggeringPrincipal;
+}
+
+void InterceptionInfo::SetTriggeringPrincipal(nsIPrincipal* aPrincipal) {
+ mTriggeringPrincipal = aPrincipal;
+}
+
+nsContentPolicyType InterceptionInfo::ContentPolicyType() {
+ return mContentPolicyType;
+}
+
+nsContentPolicyType InterceptionInfo::ExternalContentPolicyType() {
+ return static_cast<nsContentPolicyType>(
+ nsContentUtils::InternalContentPolicyTypeToExternal(mContentPolicyType));
+}
+
+void InterceptionInfo::SetContentPolicyType(
+ const nsContentPolicyType aContentPolicyType) {
+ mContentPolicyType = aContentPolicyType;
+}
+
+const RedirectHistoryArray& InterceptionInfo::RedirectChain() {
+ return mRedirectChain;
+}
+
+void InterceptionInfo::SetRedirectChain(
+ const RedirectHistoryArray& aRedirectChain) {
+ for (auto entry : aRedirectChain) {
+ mRedirectChain.AppendElement(entry);
+ }
+}
+
+bool InterceptionInfo::FromThirdParty() { return mFromThirdParty; }
+
+void InterceptionInfo::SetFromThirdParty(bool aFromThirdParty) {
+ mFromThirdParty = aFromThirdParty;
+}
+
+} // namespace mozilla::net
diff --git a/netwerk/base/InterceptionInfo.h b/netwerk/base/InterceptionInfo.h
new file mode 100644
index 000000000000..ad2f2a449902
--- /dev/null
+++ b/netwerk/base/InterceptionInfo.h
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_net_InterceptionInfo_h
+#define mozilla_net_InterceptionInfo_h
+
+#include "nsIContentSecurityPolicy.h"
+#include "nsIInterceptionInfo.h"
+#include "nsIPrincipal.h"
+#include "nsIRedirectHistoryEntry.h"
+#include "nsTArray.h"
+#include "nsCOMPtr.h"
+
+namespace mozilla::net {
+
+using RedirectHistoryArray = nsTArray<nsCOMPtr<nsIRedirectHistoryEntry>>;
+
+class InterceptionInfo final : public nsIInterceptionInfo {
+ public:
+ NS_DECL_THREADSAFE_ISUPPORTS
+ NS_DECL_NSIINTERCEPTIONINFO
+
+ InterceptionInfo(nsIPrincipal* aTriggeringPrincipal,
+ nsContentPolicyType aContentPolicyType,
+ const RedirectHistoryArray& aRedirectChain,
+ bool aFromThirdParty);
+
+ using nsIInterceptionInfo::GetExtContentPolicyType;
+
+ private:
+ ~InterceptionInfo() = default;
+
+ nsCOMPtr<nsIPrincipal> mTriggeringPrincipal;
+ nsContentPolicyType mContentPolicyType{nsIContentPolicy::TYPE_INVALID};
+ RedirectHistoryArray mRedirectChain;
+ bool mFromThirdParty = false;
+};
+
+} // namespace mozilla::net
+
+#endif
diff --git a/netwerk/base/LoadInfo.cpp b/netwerk/base/LoadInfo.cpp
index 2bca01945ce0..8ad52e11a7bc 100644
--- a/netwerk/base/LoadInfo.cpp
+++ b/netwerk/base/LoadInfo.cpp
@@ -575,7 +575,6 @@ LoadInfo::LoadInfo(const LoadInfo& rhs)
mForcePreflight(rhs.mForcePreflight),
mIsPreflight(rhs.mIsPreflight),
mLoadTriggeredFromExternal(rhs.mLoadTriggeredFromExternal),
-
mDocumentHasUserInteracted(rhs.mDocumentHasUserInteracted),
mAllowListFutureDocumentsCreatedFromThisRedirectChain(
rhs.mAllowListFutureDocumentsCreatedFromThisRedirectChain),
@@ -595,7 +594,8 @@ LoadInfo::LoadInfo(const LoadInfo& rhs)
mIsMediaInitialRequest(rhs.mIsMediaInitialRequest),
mIsFromObjectOrEmbed(rhs.mIsFromObjectOrEmbed),
mLoadingEmbedderPolicy(rhs.mLoadingEmbedderPolicy),
- mUnstrippedURI(rhs.mUnstrippedURI) {}
+ mUnstrippedURI(rhs.mUnstrippedURI),
+ mInterceptionInfo(rhs.mInterceptionInfo) {}
LoadInfo::LoadInfo(
nsIPrincipal* aLoadingPrincipal, nsIPrincipal* aTriggeringPrincipal,
@@ -636,7 +636,7 @@ LoadInfo::LoadInfo(
bool aHasStoragePermission, bool aIsMetaRefresh,
uint32_t aRequestBlockingReason, nsINode* aLoadingContext,
nsILoadInfo::CrossOriginEmbedderPolicy aLoadingEmbedderPolicy,
- nsIURI* aUnstrippedURI)
+ nsIURI* aUnstrippedURI, nsIInterceptionInfo* aInterceptionInfo)
: mLoadingPrincipal(aLoadingPrincipal),
mTriggeringPrincipal(aTriggeringPrincipal),
mPrincipalToInherit(aPrincipalToInherit),
@@ -701,9 +701,9 @@ LoadInfo::LoadInfo(
mParserCreatedScript(aParserCreatedScript),
mHasStoragePermission(aHasStoragePermission),
mIsMetaRefresh(aIsMetaRefresh),
-
mLoadingEmbedderPolicy(aLoadingEmbedderPolicy),
- mUnstrippedURI(aUnstrippedURI) {
+ mUnstrippedURI(aUnstrippedURI),
+ mInterceptionInfo(aInterceptionInfo){
// Only top level TYPE_DOCUMENT loads can have a null loadingPrincipal
MOZ_ASSERT(mLoadingPrincipal ||
aContentPolicyType == nsIContentPolicy::TYPE_DOCUMENT);
@@ -1951,5 +1951,11 @@ already_AddRefed<nsIContentSecurityPolicy> LoadInfo::GetCspToInherit() {
return cspToInherit.forget();
}
+nsIInterceptionInfo* LoadInfo::InterceptionInfo() { return mInterceptionInfo; }
+
+void LoadInfo::SetInterceptionInfo(nsIInterceptionInfo* aInfo) {
+ mInterceptionInfo = aInfo;
+}
+
} // namespace net
} // namespace mozilla
diff --git a/netwerk/base/LoadInfo.h b/netwerk/base/LoadInfo.h
index e4a93d501e95..e5f3f50e26e8 100644
--- a/netwerk/base/LoadInfo.h
+++ b/netwerk/base/LoadInfo.h
@@ -8,6 +8,7 @@
#define mozilla_LoadInfo_h
#include "nsIContentSecurityPolicy.h"
+#include "nsIInterceptionInfo.h"
#include "nsILoadInfo.h"
#include "nsIPrincipal.h"
#include "nsIWeakReferenceUtils.h" // for nsWeakPtr
@@ -223,7 +224,7 @@ class LoadInfo final : public nsILoadInfo {
bool aHasStoragePermission, bool aIsMetaRefresh,
uint32_t aRequestBlockingReason, nsINode* aLoadingContext,
nsILoadInfo::CrossOriginEmbedderPolicy aLoadingEmbedderPolicy,
- nsIURI* aUnstrippedURI);
+ nsIURI* aUnstrippedURI, nsIInterceptionInfo* aInterceptionInfo);
LoadInfo(const LoadInfo& rhs);
NS_IMETHOD GetRedirects(JSContext* aCx,
@@ -346,6 +347,8 @@ class LoadInfo final : public nsILoadInfo {
nsILoadInfo::EMBEDDER_POLICY_NULL;
nsCOMPtr<nsIURI> mUnstrippedURI;
+
+ nsCOMPtr<nsIInterceptionInfo> mInterceptionInfo;
};
} // namespace net
diff --git a/netwerk/base/TRRLoadInfo.cpp b/netwerk/base/TRRLoadInfo.cpp
index 563abe8f7d04..e341fe811ddd 100644
--- a/netwerk/base/TRRLoadInfo.cpp
+++ b/netwerk/base/TRRLoadInfo.cpp
@@ -724,5 +724,8 @@ TRRLoadInfo::GetUnstrippedURI(nsIURI** aURI) {
NS_IMETHODIMP
TRRLoadInfo::SetUnstrippedURI(nsIURI* aURI) { return NS_ERROR_NOT_IMPLEMENTED; }
+nsIInterceptionInfo* TRRLoadInfo::InterceptionInfo() { return nullptr; }
+void TRRLoadInfo::SetInterceptionInfo(nsIInterceptionInfo* aPrincipla) {}
+
} // namespace net
} // namespace mozilla
diff --git a/netwerk/base/moz.build b/netwerk/base/moz.build
index 64295118f10b..4a18f1cb32b9 100644
--- a/netwerk/base/moz.build
+++ b/netwerk/base/moz.build
@@ -47,6 +47,7 @@ XPIDL_SOURCES += [
"nsIIncrementalStreamLoader.idl",
"nsIInputStreamChannel.idl",
"nsIInputStreamPump.idl",
+ "nsIInterceptionInfo.idl",
"nsIIOService.idl",
"nsILoadContextInfo.idl",
"nsILoadGroup.idl",
@@ -159,6 +160,7 @@ EXPORTS.mozilla.net += [
"Dashboard.h",
"DashboardTypes.h",
"DefaultURI.h",
+ "InterceptionInfo.h",
"IOActivityMonitor.h",
"MemoryDownloader.h",
"NetworkConnectivityService.h",
@@ -179,6 +181,7 @@ UNIFIED_SOURCES += [
"Dashboard.cpp",
"DefaultURI.cpp",
"EventTokenBucket.cpp",
+ "InterceptionInfo.cpp",
"IOActivityMonitor.cpp",
"LoadContextInfo.cpp",
"LoadInfo.cpp",
diff --git a/netwerk/base/nsIInterceptionInfo.idl b/netwerk/base/nsIInterceptionInfo.idl
new file mode 100644
index 000000000000..d3c1b030ac55
--- /dev/null
+++ b/netwerk/base/nsIInterceptionInfo.idl
@@ -0,0 +1,73 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: ft=cpp tw=78 sw=2 et ts=2 sts=2 cin
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.idl"
+#include "nsIContentPolicy.idl"
+
+interface nsIPrincipal;
+interface nsIRedirectHistoryEntry;
+
+%{C++
+#include "nsTArray.h"
+%}
+
+[ref] native nsIRedirectHistoryEntryArray(const nsTArray<nsCOMPtr<nsIRedirectHistoryEntry>>);
+/**
+ * nsIInterceptionInfo is used to record the needed information of the
+ * InterceptedHttpChannel.
+ * This infomration need to be propagated to the new channel which created by
+ * FetchEvent.request or ServiceWorker NavigationPreload.
+ */
+[scriptable, builtinclass, uuid(8b9cd81f-3cd1-4f6a-9086-92a9bbf055f4)]
+interface nsIInterceptionInfo : nsISupports
+{
+ /**
+ * InterceptedHttpChannel's triggering principal
+ */
+ [noscript, notxpcom, nostdcall, binaryname(TriggeringPrincipal)]
+ nsIPrincipal binaryTriggeringPrincipal();
+
+ [noscript, notxpcom, nostdcall, binaryname(SetTriggeringPrincipal)]
+ void binarySetTriggeringPrincipal(in nsIPrincipal aPrincipal);
+
+ /**
+ * InterceptedHttpChannel's content policy type
+ */
+ [noscript, notxpcom, nostdcall, binaryname(ContentPolicyType)]
+ nsContentPolicyType binaryContentPolicyType();
+
+ [noscript, notxpcom, nostdcall, binaryname(ExternalContentPolicyType)]
+ nsContentPolicyType binaryExternalContentPolicyType();
+
+ [noscript, notxpcom, nostdcall, binaryname(SetContentPolicyType)]
+ void binarySetContentPolicyType(in nsContentPolicyType aContentPolicyType);
+
+%{ C++
+ inline ExtContentPolicyType GetExtContentPolicyType()
+ {
+ return static_cast<ExtContentPolicyType>(ExternalContentPolicyType());
+ }
+%}
+
+ /**
+ * The InterceptedHttpChannel's redirect chain
+ */
+ [noscript, notxpcom, nostdcall, binaryname(RedirectChain)]
+ nsIRedirectHistoryEntryArray binaryRedirectChain();
+
+ [noscript, notxpcom, nostdcall, binaryname(SetRedirectChain)]
+ void binarySetRedirectChain(
+ in nsIRedirectHistoryEntryArray aRedirectChain);
+
+ /**
+ * The InterceptedHttpChannel is a third party channel or not.
+ */
+ [noscript, notxpcom, nostdcall, binaryname(FromThirdParty)]
+ bool binaryFromThirdParty();
+
+ [noscript, notxpcom, nostdcall, binaryname(SetFromThirdParty)]
+ void binarySetFromThirdParty(in bool aFromThirdParty);
+};
diff --git a/netwerk/base/nsILoadInfo.idl b/netwerk/base/nsILoadInfo.idl
index 4bc499915f17..ac9906fb3d0c 100644
--- a/netwerk/base/nsILoadInfo.idl
+++ b/netwerk/base/nsILoadInfo.idl
@@ -7,6 +7,7 @@
#include "nsISupports.idl"
#include "nsIContentPolicy.idl"
#include "nsIScriptSecurityManager.idl"
+#include "nsIInterceptionInfo.idl"
interface nsIChannel;
interface nsIContentSecurityPolicy;
@@ -654,8 +655,10 @@ interface nsILoadInfo : nsISupports
MOZ_ASSERT(NS_SUCCEEDED(rv));
return static_cast<ExtContentPolicyType>(result);
}
+
%}
+
/**
* The internal contentPolicyType of the channel, used for constructing
* RequestContext values when creating a fetch event for an intercepted
@@ -1384,4 +1387,16 @@ interface nsILoadInfo : nsISupports
* stripping was performed.
*/
attribute nsIURI unstrippedURI;
+
+ /**
+ * Propagated information from InterceptedHttpChannel
+ * It should be null when the channel is not created from FetchEvent.request
+ * or ServiceWorker NavigationPreload.
+ * nsIFetchEventInfo is C++ only, so it is not an attribute.
+ */
+ [noscript, notxpcom, nostdcall, binaryname(InterceptionInfo)]
+ nsIInterceptionInfo binaryInterceptionInfo();
+
+ [noscript, notxpcom, nostdcall, binaryname(SetInterceptionInfo)]
+ void binarySetInterceptionInfo(in nsIInterceptionInfo info);
};
diff --git a/netwerk/cookie/CookieCommons.cpp b/netwerk/cookie/CookieCommons.cpp
index 2137877725bd..a7635d383b93 100644
--- a/netwerk/cookie/CookieCommons.cpp
+++ b/netwerk/cookie/CookieCommons.cpp
@@ -475,12 +475,25 @@ bool CookieCommons::IsSafeTopLevelNav(nsIChannel* aChannel) {
return false;
}
nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
- if (loadInfo->GetExternalContentPolicyType() !=
+ nsCOMPtr<nsIInterceptionInfo> interceptionInfo = loadInfo->InterceptionInfo();
+ if ((loadInfo->GetExternalContentPolicyType() !=
+ ExtContentPolicy::TYPE_DOCUMENT &&
+ loadInfo->GetExternalContentPolicyType() !=
+ ExtContentPolicy::TYPE_SAVEAS_DOWNLOAD) &&
+ !interceptionInfo) {
+ return false;
+ }
+
+ if (interceptionInfo &&
+ interceptionInfo->GetExtContentPolicyType() !=
ExtContentPolicy::TYPE_DOCUMENT &&
- loadInfo->GetExternalContentPolicyType() !=
- ExtContentPolicy::TYPE_SAVEAS_DOWNLOAD) {
+ interceptionInfo->GetExtContentPolicyType() !=
+ ExtContentPolicy::TYPE_SAVEAS_DOWNLOAD &&
+ interceptionInfo->GetExtContentPolicyType() !=
+ ExtContentPolicy::TYPE_INVALID) {
return false;
}
+
return NS_IsSafeMethodNav(aChannel);
}
@@ -492,24 +505,47 @@ bool CookieCommons::IsSameSiteForeign(nsIChannel* aChannel, nsIURI* aHostURI) {
// Do not treat loads triggered by web extensions as foreign
nsCOMPtr<nsIURI> channelURI;
NS_GetFinalChannelURI(aChannel, getter_AddRefs(channelURI));
- RefPtr<BasePrincipal> triggeringPrincipal =
- BasePrincipal::Cast(loadInfo->TriggeringPrincipal());
- if (triggeringPrincipal->AddonPolicy() &&
- triggeringPrincipal->AddonAllowsLoad(channelURI)) {
- return false;
+
+ nsCOMPtr<nsIInterceptionInfo> interceptionInfo = loadInfo->InterceptionInfo();
+
+ RefPtr<BasePrincipal> triggeringPrincipal;
+ ExtContentPolicy contentPolicyType;
+ if (interceptionInfo && interceptionInfo->TriggeringPrincipal()) {
+ triggeringPrincipal =
+ BasePrincipal::Cast(interceptionInfo->TriggeringPrincipal());
+ contentPolicyType = interceptionInfo->GetExtContentPolicyType();
+ } else {
+ triggeringPrincipal = BasePrincipal::Cast(loadInfo->TriggeringPrincipal());
+ contentPolicyType = loadInfo->GetExternalContentPolicyType();
+
+ if (triggeringPrincipal->AddonPolicy() &&
+ triggeringPrincipal->AddonAllowsLoad(channelURI)) {
+ return false;
+ }
}
+ const nsTArray<nsCOMPtr<nsIRedirectHistoryEntry>>& redirectChain(
+ interceptionInfo && interceptionInfo->TriggeringPrincipal()
+ ? interceptionInfo->RedirectChain()
+ : loadInfo->RedirectChain());
bool isForeign = true;
nsresult rv;
- if (loadInfo->GetExternalContentPolicyType() ==
- ExtContentPolicy::TYPE_DOCUMENT ||
- loadInfo->GetExternalContentPolicyType() ==
- ExtContentPolicy::TYPE_SAVEAS_DOWNLOAD) {
+ if (contentPolicyType == ExtContentPolicy::TYPE_DOCUMENT ||
+ contentPolicyType == ExtContentPolicy::TYPE_SAVEAS_DOWNLOAD) {
// for loads of TYPE_DOCUMENT we query the hostURI from the
// triggeringPrincipal which returns the URI of the document that caused the
// navigation.
rv = triggeringPrincipal->IsThirdPartyChannel(aChannel, &isForeign);
} else {
+ // If the load is caused by FetchEvent.request or NavigationPreload request,
+ // check the original InterceptedHttpChannel is a third-party channel or
+ // not.
+ if (interceptionInfo && interceptionInfo->TriggeringPrincipal()) {
+ isForeign = interceptionInfo->FromThirdParty();
+ if (isForeign) {
+ return true;
+ }
+ }
nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil =
do_GetService(THIRDPARTYUTIL_CONTRACTID);
if (!thirdPartyUtil) {
@@ -528,10 +564,8 @@ bool CookieCommons::IsSameSiteForeign(nsIChannel* aChannel, nsIURI* aHostURI) {
// iframe which would send same-site cookies. Hence, if the iframe navigation
// was triggered by a cross-origin triggeringPrincipal, we treat the load as
// foreign.
- if (loadInfo->GetExternalContentPolicyType() ==
- ExtContentPolicy::TYPE_SUBDOCUMENT) {
- rv = loadInfo->TriggeringPrincipal()->IsThirdPartyChannel(aChannel,
- &isForeign);
+ if (contentPolicyType == ExtContentPolicy::TYPE_SUBDOCUMENT) {
+ rv = triggeringPrincipal->IsThirdPartyChannel(aChannel, &isForeign);
if (NS_FAILED(rv) || isForeign) {
return true;
}
@@ -542,7 +576,7 @@ bool CookieCommons::IsSameSiteForeign(nsIChannel* aChannel, nsIURI* aHostURI) {
// with regards to CSRF.
nsCOMPtr<nsIPrincipal> redirectPrincipal;
- for (nsIRedirectHistoryEntry* entry : loadInfo->RedirectChain()) {
+ for (nsIRedirectHistoryEntry* entry : redirectChain) {
entry->GetPrincipal(getter_AddRefs(redirectPrincipal));
if (redirectPrincipal) {
rv = redirectPrincipal->IsThirdPartyChannel(aChannel, &isForeign);
diff --git a/netwerk/ipc/NeckoChannelParams.ipdlh b/netwerk/ipc/NeckoChannelParams.ipdlh
index 89eabe2c74bc..f051d377b78f 100644
--- a/netwerk/ipc/NeckoChannelParams.ipdlh
+++ b/netwerk/ipc/NeckoChannelParams.ipdlh
@@ -76,6 +76,14 @@ struct RedirectHistoryEntryInfo
nsCString remoteAddress;
};
+struct InterceptionInfoArg
+{
+ PrincipalInfo? triggeringPrincipalInfo;
+ nsContentPolicyType contentPolicyType;
+ RedirectHistoryEntryInfo[] redirectChain;
+ bool fromThirdParty;
+};
+
struct LoadInfoArgs
{
PrincipalInfo? requestingPrincipalInfo;
@@ -161,6 +169,7 @@ struct LoadInfoArgs
bool isMetaRefresh;
CrossOriginEmbedderPolicy loadingEmbedderPolicy;
nsIURI unstrippedURI;
+ InterceptionInfoArg? interceptionInfo;
};
/**
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the tbb-commits
mailing list