[tbb-commits] [tor-browser] 09/46: 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
Wed Nov 16 20:42:49 UTC 2022
This is an automated email from the git hooks/post-receive script.
richard pushed a commit to branch base-browser-102.5.0esr-12.0-1
in repository tor-browser.
commit 566f5b90b069fdf3a33eea31c78c7762e1131f2e
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 de3778e26528..f987bfbb4789 100644
--- a/dom/fetch/Fetch.cpp
+++ b/dom/fetch/Fetch.cpp
@@ -486,6 +486,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 69ac87423329..34b0fbd61b09 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"
@@ -38,6 +40,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"
@@ -646,6 +649,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 6e9269d93851..89aeebc2b4a0 100644
--- a/dom/fetch/FetchTypes.ipdlh
+++ b/dom/fetch/FetchTypes.ipdlh
@@ -6,6 +6,7 @@ include IPCStream;
include IPCChannelInfo;
include PBackgroundSharedTypes;
include PerformanceTimingTypes;
+include NeckoChannelParams;
include "mozilla/dom/FetchIPCTypes.h";
@@ -65,6 +66,10 @@ struct IPCInternalRequest {
nsString integrity;
nsCString fragment;
PrincipalInfo? principalInfo;
+ PrincipalInfo? interceptionTriggeringPrincipalInfo;
+ uint32_t interceptionContentPolicyType;
+ RedirectHistoryEntryInfo[] interceptionRedirectChain;
+ bool interceptionFromThirdParty;
};
struct InternalResponseMetadata {
diff --git a/dom/fetch/InternalRequest.cpp b/dom/fetch/InternalRequest.cpp
index 0a5b66b0bc52..65ade82a5f53 100644
--- a/dom/fetch/InternalRequest.cpp
+++ b/dom/fetch/InternalRequest.cpp
@@ -139,8 +139,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)
@@ -159,12 +168,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) {
@@ -399,4 +423,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 1b69011df86d..cf122482f8dd 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 {
@@ -326,7 +329,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;
}
@@ -351,6 +353,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 {};
@@ -425,6 +457,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 9406c5ec60e8..2317f3484637 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"
@@ -841,11 +843,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
@@ -854,7 +878,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 df63b2b4b123..450da19e8bcb 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"
@@ -497,6 +498,29 @@ nsresult LoadInfoToLoadInfoArgs(nsILoadInfo* aLoadInfo,
aLoadInfo->GetIsThirdPartyContextToTopWindow());
}
+ 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,
topLevelPrincipalInfo, optionalResultPrincipalURI,
@@ -537,7 +561,8 @@ nsresult LoadInfoToLoadInfoArgs(nsILoadInfo* aLoadInfo,
aLoadInfo->GetIsFromObjectOrEmbed(), cookieJarSettingsArgs,
aLoadInfo->GetRequestBlockingReason(), maybeCspToInheritInfo,
aLoadInfo->GetStoragePermission(), aLoadInfo->GetIsMetaRefresh(),
- aLoadInfo->GetLoadingEmbedderPolicy(), unstrippedURI));
+ aLoadInfo->GetLoadingEmbedderPolicy(), unstrippedURI,
+ interceptionInfoArg));
return NS_OK;
}
@@ -665,7 +690,6 @@ nsresult LoadInfoArgsToLoadInfo(
NS_ENSURE_SUCCESS(rv, rv);
redirectChain.AppendElement(redirectHistoryEntry.forget());
}
-
nsTArray<nsCOMPtr<nsIPrincipal>> ancestorPrincipals;
nsTArray<uint64_t> ancestorBrowsingContextIDs;
if (XRE_IsParentProcess() &&
@@ -740,6 +764,34 @@ nsresult LoadInfoArgsToLoadInfo(
loadInfoArgs.isThirdPartyContextToTopWindow().ref());
}
+ 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,
topLevelPrincipal, resultPrincipalURI, cookieJarSettings, cspToInherit,
@@ -779,7 +831,8 @@ nsresult LoadInfoArgsToLoadInfo(
loadInfoArgs.isInDevToolsContext(), loadInfoArgs.parserCreatedScript(),
loadInfoArgs.storagePermission(), 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 5f5f9d051476..36b9416c5d28 100644
--- a/netwerk/base/LoadInfo.cpp
+++ b/netwerk/base/LoadInfo.cpp
@@ -570,7 +570,6 @@ LoadInfo::LoadInfo(const LoadInfo& rhs)
mForcePreflight(rhs.mForcePreflight),
mIsPreflight(rhs.mIsPreflight),
mLoadTriggeredFromExternal(rhs.mLoadTriggeredFromExternal),
-
mDocumentHasUserInteracted(rhs.mDocumentHasUserInteracted),
mAllowListFutureDocumentsCreatedFromThisRedirectChain(
rhs.mAllowListFutureDocumentsCreatedFromThisRedirectChain),
@@ -590,7 +589,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,
@@ -629,7 +629,7 @@ LoadInfo::LoadInfo(
nsILoadInfo::StoragePermissionState aStoragePermission, bool aIsMetaRefresh,
uint32_t aRequestBlockingReason, nsINode* aLoadingContext,
nsILoadInfo::CrossOriginEmbedderPolicy aLoadingEmbedderPolicy,
- nsIURI* aUnstrippedURI)
+ nsIURI* aUnstrippedURI, nsIInterceptionInfo* aInterceptionInfo)
: mLoadingPrincipal(aLoadingPrincipal),
mTriggeringPrincipal(aTriggeringPrincipal),
mPrincipalToInherit(aPrincipalToInherit),
@@ -694,9 +694,9 @@ LoadInfo::LoadInfo(
mParserCreatedScript(aParserCreatedScript),
mStoragePermission(aStoragePermission),
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);
@@ -2153,4 +2153,10 @@ already_AddRefed<nsIContentSecurityPolicy> LoadInfo::GetCspToInherit() {
return cspToInherit.forget();
}
+nsIInterceptionInfo* LoadInfo::InterceptionInfo() { return mInterceptionInfo; }
+
+void LoadInfo::SetInterceptionInfo(nsIInterceptionInfo* aInfo) {
+ mInterceptionInfo = aInfo;
+}
+
} // namespace mozilla::net
diff --git a/netwerk/base/LoadInfo.h b/netwerk/base/LoadInfo.h
index a1624592d20d..dbe042b1bf04 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
@@ -230,7 +231,7 @@ class LoadInfo final : public nsILoadInfo {
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,
@@ -357,6 +358,8 @@ class LoadInfo final : public nsILoadInfo {
nsILoadInfo::EMBEDDER_POLICY_NULL;
nsCOMPtr<nsIURI> mUnstrippedURI;
+
+ nsCOMPtr<nsIInterceptionInfo> mInterceptionInfo;
};
// This is exposed solely for testing purposes and should not be used outside of
diff --git a/netwerk/base/TRRLoadInfo.cpp b/netwerk/base/TRRLoadInfo.cpp
index 05a8878a3f26..0d05aaeb6872 100644
--- a/netwerk/base/TRRLoadInfo.cpp
+++ b/netwerk/base/TRRLoadInfo.cpp
@@ -748,5 +748,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 acfca9ff113b..4bcff33bde4f 100644
--- a/netwerk/base/moz.build
+++ b/netwerk/base/moz.build
@@ -46,6 +46,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",
@@ -178,6 +180,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 85ba87970298..f1b110917e5f 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;
@@ -675,8 +676,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
@@ -1415,4 +1418,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 7ecbadef868b..b09541ad65b7 100644
--- a/netwerk/cookie/CookieCommons.cpp
+++ b/netwerk/cookie/CookieCommons.cpp
@@ -483,12 +483,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);
}
@@ -530,22 +543,36 @@ 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());
nsAutoCString hostScheme, otherScheme;
aHostURI->GetScheme(hostScheme);
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.
@@ -553,6 +580,15 @@ bool CookieCommons::IsSameSiteForeign(nsIChannel* aChannel, nsIURI* aHostURI,
triggeringPrincipal->GetScheme(otherScheme);
} 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) {
@@ -579,10 +615,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;
}
@@ -593,7 +627,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 91484637f1a8..8d8075a59e8d 100644
--- a/netwerk/ipc/NeckoChannelParams.ipdlh
+++ b/netwerk/ipc/NeckoChannelParams.ipdlh
@@ -80,6 +80,14 @@ struct RedirectHistoryEntryInfo
nsCString remoteAddress;
};
+struct InterceptionInfoArg
+{
+ PrincipalInfo? triggeringPrincipalInfo;
+ nsContentPolicyType contentPolicyType;
+ RedirectHistoryEntryInfo[] redirectChain;
+ bool fromThirdParty;
+};
+
struct LoadInfoArgs
{
PrincipalInfo? requestingPrincipalInfo;
@@ -164,6 +172,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