From 06a4432ed1dcf9d09a332acf9c11df171eb89679 Mon Sep 17 00:00:00 2001 From: Benjamin VanderSloot Date: Mon, 14 Aug 2023 18:02:46 +0000 Subject: [PATCH] Bug 1835907, part 1 - Add has storage access bit and triggering window id to the LoadInfo - r=smaug,necko-reviewers,kershaw,pbz In the Storage Access API's latest draft, a few items were added to the user-agent state. Relevant here, the source snapshot params gained two fields that are initialized from the sourceDocument during snapshotting source params while navigating: "has storage access" and "environment id". https://privacycg.github.io/storage-access/#ua-state These are used to identify self-initiated navigations that come from documents that have obtained storage access. Combined with a same-origin check, this determines if the destination document of the navigation should start with storage access. This is stricter than the current behavior, where if the permission is available, all documents start with storage access. Instead, now a document will only have storage access if it requests it explicitly or if a same-origin document that has storage access navigates itself to that document. This is seen as a security win. Security discussion of this change was here: https://github.com/privacycg/storage-access/issues/113 Artur at Google wrote up a great summary here: https://docs.google.com/document/d/1AsrETl-7XvnZNbG81Zy9BcZfKbqACQYBSrjM3VsIpjY/edit# Differential Revision: https://phabricator.services.mozilla.com/D184821 --- docshell/base/nsDocShell.cpp | 38 ++++++++++++++++++- docshell/base/nsDocShellLoadState.cpp | 28 ++++++++++++++ docshell/base/nsDocShellLoadState.h | 14 +++++++ dom/ipc/DOMTypes.ipdlh | 2 + dom/webidl/LoadURIOptions.webidl | 9 +++++ ipc/glue/BackgroundUtils.cpp | 14 ++++++- netwerk/base/LoadInfo.cpp | 31 ++++++++++++++- netwerk/base/LoadInfo.h | 5 ++- netwerk/base/TRRLoadInfo.cpp | 18 +++++++++ netwerk/base/nsILoadInfo.idl | 10 +++++ netwerk/ipc/DocumentLoadListener.cpp | 4 ++ netwerk/ipc/NeckoChannelParams.ipdlh | 8 ++++ .../windowwatcher/nsWindowWatcher.cpp | 6 +++ 13 files changed, 182 insertions(+), 5 deletions(-) diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 555fb05473fd44..14924b6066ede5 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -4014,6 +4014,13 @@ nsresult nsDocShell::LoadErrorPage(nsIURI* aErrorURI, nsIURI* aFailedURI, loadState->SetTriggeringPrincipal(nsContentUtils::GetSystemPrincipal()); if (mBrowsingContext) { loadState->SetTriggeringSandboxFlags(mBrowsingContext->GetSandboxFlags()); + loadState->SetTriggeringWindowId( + mBrowsingContext->GetCurrentInnerWindowId()); + nsPIDOMWindowInner* innerWin = mScriptGlobal->GetCurrentInnerWindow(); + if (innerWin) { + loadState->SetTriggeringStorageAccess( + innerWin->HasStorageAccessPermissionGranted()); + } } loadState->SetLoadType(LOAD_ERROR_PAGE); loadState->SetFirstParty(true); @@ -4200,6 +4207,8 @@ nsresult nsDocShell::ReloadDocument(nsDocShell* aDocShell, Document* aDocument, nsIPrincipal* triggeringPrincipal = aDocument->NodePrincipal(); nsCOMPtr csp = aDocument->GetCsp(); uint32_t triggeringSandboxFlags = aDocument->GetSandboxFlags(); + uint64_t triggeringWindowId = aDocument->InnerWindowID(); + bool triggeringStorageAccess = aDocument->HasStorageAccessPermissionGranted(); nsAutoString contentTypeHint; aDocument->GetContentType(contentTypeHint); @@ -4246,6 +4255,8 @@ nsresult nsDocShell::ReloadDocument(nsDocShell* aDocShell, Document* aDocument, loadState->SetLoadReplace(loadReplace); loadState->SetTriggeringPrincipal(triggeringPrincipal); loadState->SetTriggeringSandboxFlags(triggeringSandboxFlags); + loadState->SetTriggeringWindowId(triggeringWindowId); + loadState->SetTriggeringStorageAccess(triggeringStorageAccess); loadState->SetPrincipalToInherit(triggeringPrincipal); loadState->SetCsp(csp); loadState->SetInternalLoadFlags(flags); @@ -5233,6 +5244,9 @@ nsDocShell::ForceRefreshURI(nsIURI* aURI, nsIPrincipal* aPrincipal, loadState->SetHasValidUserGestureActivation( doc->HasValidTransientUserGestureActivation()); loadState->SetTriggeringSandboxFlags(doc->GetSandboxFlags()); + loadState->SetTriggeringWindowId(doc->InnerWindowID()); + loadState->SetTriggeringStorageAccess( + doc->HasStorageAccessPermissionGranted()); } loadState->SetPrincipalIsExplicit(true); @@ -8574,6 +8588,9 @@ nsresult nsDocShell::PerformRetargeting(nsDocShellLoadState* aLoadState) { loadState->SetTriggeringPrincipal(aLoadState->TriggeringPrincipal()); loadState->SetTriggeringSandboxFlags( aLoadState->TriggeringSandboxFlags()); + loadState->SetTriggeringWindowId(aLoadState->TriggeringWindowId()); + loadState->SetTriggeringStorageAccess( + aLoadState->TriggeringStorageAccess()); loadState->SetCsp(aLoadState->Csp()); loadState->SetInheritPrincipal(aLoadState->HasInternalLoadFlags( INTERNAL_LOAD_FLAGS_INHERIT_PRINCIPAL)); @@ -10511,9 +10528,16 @@ nsresult nsDocShell::DoURILoad(nsDocShellLoadState* aLoadState, } } - if (mLoadType != LOAD_ERROR_PAGE && context && context->IsInProcess() && - context->HasValidTransientUserGestureActivation()) { + if (mLoadType != LOAD_ERROR_PAGE && context && context->IsInProcess()) { aLoadState->SetHasValidUserGestureActivation(true); + aLoadState->SetTriggeringWindowId(context->Id()); + if (!aLoadState->TriggeringStorageAccess()) { + Document* contextDoc = context->GetExtantDoc(); + if (contextDoc) { + aLoadState->SetTriggeringStorageAccess( + contextDoc->HasStorageAccessPermissionGranted()); + } + } } // in case this docshell load was triggered by a valid transient user gesture, @@ -10523,6 +10547,9 @@ nsresult nsDocShell::DoURILoad(nsDocShellLoadState* aLoadState, aLoadState->HasLoadFlags(LOAD_FLAGS_FROM_EXTERNAL)) { loadInfo->SetHasValidUserGestureActivation(true); } + + loadInfo->SetTriggeringWindowId(aLoadState->TriggeringWindowId()); + loadInfo->SetTriggeringStorageAccess(aLoadState->TriggeringStorageAccess()); loadInfo->SetTriggeringSandboxFlags(aLoadState->TriggeringSandboxFlags()); loadInfo->SetIsMetaRefresh(aLoadState->IsMetaRefresh()); @@ -13040,8 +13067,13 @@ nsresult nsDocShell::OnLinkClickSync(nsIContent* aContent, } } uint32_t triggeringSandboxFlags = 0; + uint64_t triggeringWindowId = 0; + bool triggeringStorageAccess = false; if (mBrowsingContext) { triggeringSandboxFlags = aContent->OwnerDoc()->GetSandboxFlags(); + triggeringWindowId = aContent->OwnerDoc()->InnerWindowID(); + triggeringStorageAccess = + aContent->OwnerDoc()->HasStorageAccessPermissionGranted(); } uint32_t flags = INTERNAL_LOAD_FLAGS_NONE; @@ -13149,6 +13181,8 @@ nsresult nsDocShell::OnLinkClickSync(nsIContent* aContent, RefPtr context = mBrowsingContext->GetCurrentWindowContext(); aLoadState->SetTriggeringSandboxFlags(triggeringSandboxFlags); + aLoadState->SetTriggeringWindowId(triggeringWindowId); + aLoadState->SetTriggeringStorageAccess(triggeringStorageAccess); aLoadState->SetReferrerInfo(referrerInfo); aLoadState->SetInternalLoadFlags(flags); aLoadState->SetTypeHint(NS_ConvertUTF16toUTF8(typeHint)); diff --git a/docshell/base/nsDocShellLoadState.cpp b/docshell/base/nsDocShellLoadState.cpp index 0c250b1280b3e8..82691d13d2d5f8 100644 --- a/docshell/base/nsDocShellLoadState.cpp +++ b/docshell/base/nsDocShellLoadState.cpp @@ -86,6 +86,8 @@ nsDocShellLoadState::nsDocShellLoadState( mPrincipalToInherit = aLoadState.PrincipalToInherit(); mPartitionedPrincipalToInherit = aLoadState.PartitionedPrincipalToInherit(); mTriggeringSandboxFlags = aLoadState.TriggeringSandboxFlags(); + mTriggeringWindowId = aLoadState.TriggeringWindowId(); + mTriggeringStorageAccess = aLoadState.TriggeringStorageAccess(); mTriggeringRemoteType = aLoadState.TriggeringRemoteType(); mCsp = aLoadState.Csp(); mOriginalURIString = aLoadState.OriginalURIString(); @@ -150,6 +152,8 @@ nsDocShellLoadState::nsDocShellLoadState(const nsDocShellLoadState& aOther) mResultPrincipalURIIsSome(aOther.mResultPrincipalURIIsSome), mTriggeringPrincipal(aOther.mTriggeringPrincipal), mTriggeringSandboxFlags(aOther.mTriggeringSandboxFlags), + mTriggeringWindowId(aOther.mTriggeringWindowId), + mTriggeringStorageAccess(aOther.mTriggeringStorageAccess), mCsp(aOther.mCsp), mKeepResultPrincipalURIIfSet(aOther.mKeepResultPrincipalURIIfSet), mLoadReplace(aOther.mLoadReplace), @@ -204,6 +208,8 @@ nsDocShellLoadState::nsDocShellLoadState(nsIURI* aURI, uint64_t aLoadIdentifier) : mURI(aURI), mResultPrincipalURIIsSome(false), mTriggeringSandboxFlags(0), + mTriggeringWindowId(0), + mTriggeringStorageAccess(false), mKeepResultPrincipalURIIfSet(false), mLoadReplace(false), mInheritPrincipal(false), @@ -443,6 +449,9 @@ nsresult nsDocShellLoadState::CreateFromLoadURIOptions( loadState->SetHasValidUserGestureActivation( aLoadURIOptions.mHasValidUserGestureActivation); loadState->SetTriggeringSandboxFlags(aLoadURIOptions.mTriggeringSandboxFlags); + loadState->SetTriggeringWindowId(aLoadURIOptions.mTriggeringWindowId); + loadState->SetTriggeringStorageAccess( + aLoadURIOptions.mTriggeringStorageAccess); loadState->SetPostDataStream(postData); loadState->SetHeadersStream(aLoadURIOptions.mHeaders); loadState->SetBaseURI(aLoadURIOptions.mBaseURI); @@ -562,6 +571,23 @@ uint32_t nsDocShellLoadState::TriggeringSandboxFlags() const { return mTriggeringSandboxFlags; } +void nsDocShellLoadState::SetTriggeringWindowId(uint64_t aTriggeringWindowId) { + mTriggeringWindowId = aTriggeringWindowId; +} + +uint64_t nsDocShellLoadState::TriggeringWindowId() const { + return mTriggeringWindowId; +} + +void nsDocShellLoadState::SetTriggeringStorageAccess( + bool aTriggeringStorageAccess) { + mTriggeringStorageAccess = aTriggeringStorageAccess; +} + +bool nsDocShellLoadState::TriggeringStorageAccess() const { + return mTriggeringStorageAccess; +} + bool nsDocShellLoadState::InheritPrincipal() const { return mInheritPrincipal; } void nsDocShellLoadState::SetInheritPrincipal(bool aInheritPrincipal) { @@ -1253,6 +1279,8 @@ DocShellLoadStateInit nsDocShellLoadState::Serialize( loadState.PrincipalToInherit() = mPrincipalToInherit; loadState.PartitionedPrincipalToInherit() = mPartitionedPrincipalToInherit; loadState.TriggeringSandboxFlags() = mTriggeringSandboxFlags; + loadState.TriggeringWindowId() = mTriggeringWindowId; + loadState.TriggeringStorageAccess() = mTriggeringStorageAccess; loadState.TriggeringRemoteType() = mTriggeringRemoteType; loadState.Csp() = mCsp; loadState.OriginalURIString() = mOriginalURIString; diff --git a/docshell/base/nsDocShellLoadState.h b/docshell/base/nsDocShellLoadState.h index a1e0416409e0f2..0ae5bfbd2a8568 100644 --- a/docshell/base/nsDocShellLoadState.h +++ b/docshell/base/nsDocShellLoadState.h @@ -113,6 +113,14 @@ class nsDocShellLoadState final { void SetTriggeringSandboxFlags(uint32_t aTriggeringSandboxFlags); + uint64_t TriggeringWindowId() const; + + void SetTriggeringWindowId(uint64_t aTriggeringWindowId); + + bool TriggeringStorageAccess() const; + + void SetTriggeringStorageAccess(bool aTriggeringStorageAccess); + nsIContentSecurityPolicy* Csp() const; void SetCsp(nsIContentSecurityPolicy* aCsp); @@ -413,6 +421,12 @@ class nsDocShellLoadState final { // SandboxFlags of the document that started the load. uint32_t mTriggeringSandboxFlags; + // The window ID and current "has storage access" value of the entity + // triggering the load. This allows the identification of self-initiated + // same-origin navigations that should propogate unpartitioned storage access. + uint64_t mTriggeringWindowId; + bool mTriggeringStorageAccess; + // The CSP of the load, that is, the CSP of the entity responsible for causing // the load to occur. Most likely this is the CSP of the document that started // the load. In case the entity starting the load did not use a CSP, then mCsp diff --git a/dom/ipc/DOMTypes.ipdlh b/dom/ipc/DOMTypes.ipdlh index 2fbe80e42a999f..5b5f6cac32d9fb 100644 --- a/dom/ipc/DOMTypes.ipdlh +++ b/dom/ipc/DOMTypes.ipdlh @@ -200,6 +200,8 @@ struct DocShellLoadStateInit // The TriggineringSandboxFlags are the SandboxFlags of the entity // responsible for causing the load to occur. uint32_t TriggeringSandboxFlags; + uint64_t TriggeringWindowId; + bool TriggeringStorageAccess; int32_t? CancelContentJSEpoch; bool ResultPrincipalURIIsSome; diff --git a/dom/webidl/LoadURIOptions.webidl b/dom/webidl/LoadURIOptions.webidl index fe11a1cc8fb75f..32848cba756c39 100644 --- a/dom/webidl/LoadURIOptions.webidl +++ b/dom/webidl/LoadURIOptions.webidl @@ -75,6 +75,15 @@ dictionary LoadURIOptions { */ unsigned long triggeringSandboxFlags = 0; + /** + * The window id and storage access status of the window of the + * context that triggered the load. This is used to allow self-initiated + * same-origin navigations to propagate their "has storage access" bit + * to the next Document. + */ + unsigned long long triggeringWindowId = 0; + boolean triggeringStorageAccess = false; + /** * The RemoteType of the entity that's responsible for the load. Defaults to * the current process. diff --git a/ipc/glue/BackgroundUtils.cpp b/ipc/glue/BackgroundUtils.cpp index e8f667c7fd0e45..4daac279ad8330 100644 --- a/ipc/glue/BackgroundUtils.cpp +++ b/ipc/glue/BackgroundUtils.cpp @@ -546,6 +546,8 @@ nsresult LoadInfoToLoadInfoArgs(nsILoadInfo* aLoadInfo, topLevelPrincipalInfo, optionalResultPrincipalURI, triggeringRemoteType, aLoadInfo->GetSandboxedNullPrincipalID(), aLoadInfo->GetSecurityFlags(), aLoadInfo->GetSandboxFlags(), aLoadInfo->GetTriggeringSandboxFlags(), + aLoadInfo->GetTriggeringWindowId(), + aLoadInfo->GetTriggeringStorageAccess(), aLoadInfo->InternalContentPolicyType(), static_cast(aLoadInfo->GetTainting()), aLoadInfo->GetBlockAllMixedContent(), @@ -829,7 +831,8 @@ nsresult LoadInfoArgsToLoadInfo(const LoadInfoArgs& loadInfoArgs, triggeringRemoteType, loadInfoArgs.sandboxedNullPrincipalID(), clientInfo, reservedClientInfo, initialClientInfo, controller, loadInfoArgs.securityFlags(), loadInfoArgs.sandboxFlags(), - loadInfoArgs.triggeringSandboxFlags(), loadInfoArgs.contentPolicyType(), + loadInfoArgs.triggeringSandboxFlags(), loadInfoArgs.triggeringWindowId(), + loadInfoArgs.triggeringStorageAccess(), loadInfoArgs.contentPolicyType(), static_cast(loadInfoArgs.tainting()), loadInfoArgs.blockAllMixedContent(), loadInfoArgs.upgradeInsecureRequests(), @@ -928,6 +931,8 @@ void LoadInfoToParentLoadInfoForwarder( aLoadInfo->GetAllowDeprecatedSystemRequests(), aLoadInfo->GetIsInDevToolsContext(), aLoadInfo->GetParserCreatedScript(), aLoadInfo->GetTriggeringSandboxFlags(), + aLoadInfo->GetTriggeringWindowId(), + aLoadInfo->GetTriggeringStorageAccess(), aLoadInfo->GetServiceWorkerTaintingSynthesized(), aLoadInfo->GetDocumentHasUserInteracted(), aLoadInfo->GetAllowListFutureDocumentsCreatedFromThisRedirectChain(), @@ -971,6 +976,13 @@ nsresult MergeParentLoadInfoForwarder( aForwarderArgs.triggeringSandboxFlags()); NS_ENSURE_SUCCESS(rv, rv); + rv = aLoadInfo->SetTriggeringWindowId(aForwarderArgs.triggeringWindowId()); + NS_ENSURE_SUCCESS(rv, rv); + + rv = aLoadInfo->SetTriggeringStorageAccess( + aForwarderArgs.triggeringStorageAccess()); + NS_ENSURE_SUCCESS(rv, rv); + rv = aLoadInfo->SetHasValidUserGestureActivation( aForwarderArgs.hasValidUserGestureActivation()); NS_ENSURE_SUCCESS(rv, rv); diff --git a/netwerk/base/LoadInfo.cpp b/netwerk/base/LoadInfo.cpp index 15f38e815abe6e..5f0543bbb11788 100644 --- a/netwerk/base/LoadInfo.cpp +++ b/netwerk/base/LoadInfo.cpp @@ -576,6 +576,8 @@ LoadInfo::LoadInfo(const LoadInfo& rhs) mSecurityFlags(rhs.mSecurityFlags), mSandboxFlags(rhs.mSandboxFlags), mTriggeringSandboxFlags(rhs.mTriggeringSandboxFlags), + mTriggeringWindowId(rhs.mTriggeringWindowId), + mTriggeringStorageAccess(rhs.mTriggeringStorageAccess), mInternalContentPolicyType(rhs.mInternalContentPolicyType), mTainting(rhs.mTainting), mBlockAllMixedContent(rhs.mBlockAllMixedContent), @@ -651,7 +653,8 @@ LoadInfo::LoadInfo( const Maybe& aInitialClientInfo, const Maybe& aController, nsSecurityFlags aSecurityFlags, uint32_t aSandboxFlags, - uint32_t aTriggeringSandboxFlags, nsContentPolicyType aContentPolicyType, + uint32_t aTriggeringSandboxFlags, uint64_t aTriggeringWindowId, + bool aTriggeringStorageAccess, nsContentPolicyType aContentPolicyType, LoadTainting aTainting, bool aBlockAllMixedContent, bool aUpgradeInsecureRequests, bool aBrowserUpgradeInsecureRequests, bool aBrowserDidUpgradeInsecureRequests, @@ -699,6 +702,8 @@ LoadInfo::LoadInfo( mSecurityFlags(aSecurityFlags), mSandboxFlags(aSandboxFlags), mTriggeringSandboxFlags(aTriggeringSandboxFlags), + mTriggeringWindowId(aTriggeringWindowId), + mTriggeringStorageAccess(aTriggeringStorageAccess), mInternalContentPolicyType(aContentPolicyType), mTainting(aTainting), mBlockAllMixedContent(aBlockAllMixedContent), @@ -975,6 +980,30 @@ LoadInfo::SetTriggeringSandboxFlags(uint32_t aFlags) { return NS_OK; } +NS_IMETHODIMP +LoadInfo::GetTriggeringWindowId(uint64_t* aResult) { + *aResult = mTriggeringWindowId; + return NS_OK; +} + +NS_IMETHODIMP +LoadInfo::SetTriggeringWindowId(uint64_t aFlags) { + mTriggeringWindowId = aFlags; + return NS_OK; +} + +NS_IMETHODIMP +LoadInfo::GetTriggeringStorageAccess(bool* aResult) { + *aResult = mTriggeringStorageAccess; + return NS_OK; +} + +NS_IMETHODIMP +LoadInfo::SetTriggeringStorageAccess(bool aFlags) { + mTriggeringStorageAccess = aFlags; + return NS_OK; +} + NS_IMETHODIMP LoadInfo::GetSecurityMode(uint32_t* aFlags) { *aFlags = (mSecurityFlags & diff --git a/netwerk/base/LoadInfo.h b/netwerk/base/LoadInfo.h index c499f995484372..f97d2389297ea1 100644 --- a/netwerk/base/LoadInfo.h +++ b/netwerk/base/LoadInfo.h @@ -212,7 +212,8 @@ class LoadInfo final : public nsILoadInfo { const Maybe& aInitialClientInfo, const Maybe& aController, nsSecurityFlags aSecurityFlags, uint32_t aSandboxFlags, - uint32_t aTriggeringSandboxFlags, nsContentPolicyType aContentPolicyType, + uint32_t aTriggeringSandboxFlags, uint64_t aTriggeringWindowId, + bool aTriggeringStorageAccess, nsContentPolicyType aContentPolicyType, LoadTainting aTainting, bool aBlockAllMixedContent, bool aUpgradeInsecureRequests, bool aBrowserUpgradeInsecureRequests, bool aBrowserDidUpgradeInsecureRequests, @@ -306,6 +307,8 @@ class LoadInfo final : public nsILoadInfo { nsSecurityFlags mSecurityFlags; uint32_t mSandboxFlags; uint32_t mTriggeringSandboxFlags = 0; + uint64_t mTriggeringWindowId = 0; + bool mTriggeringStorageAccess = false; nsContentPolicyType mInternalContentPolicyType; LoadTainting mTainting = LoadTainting::Basic; bool mBlockAllMixedContent = false; diff --git a/netwerk/base/TRRLoadInfo.cpp b/netwerk/base/TRRLoadInfo.cpp index 2b9360cd23f1f2..37b0b7bfe516ca 100644 --- a/netwerk/base/TRRLoadInfo.cpp +++ b/netwerk/base/TRRLoadInfo.cpp @@ -114,6 +114,24 @@ TRRLoadInfo::SetTriggeringSandboxFlags(uint32_t aResult) { return NS_ERROR_NOT_IMPLEMENTED; } +NS_IMETHODIMP +TRRLoadInfo::GetTriggeringWindowId(uint64_t* aResult) { + return NS_ERROR_NOT_IMPLEMENTED; +} +NS_IMETHODIMP +TRRLoadInfo::SetTriggeringWindowId(uint64_t aResult) { + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +TRRLoadInfo::GetTriggeringStorageAccess(bool* aResult) { + return NS_ERROR_NOT_IMPLEMENTED; +} +NS_IMETHODIMP +TRRLoadInfo::SetTriggeringStorageAccess(bool aResult) { + return NS_ERROR_NOT_IMPLEMENTED; +} + NS_IMETHODIMP TRRLoadInfo::GetSecurityMode(uint32_t* aFlags) { return NS_ERROR_NOT_IMPLEMENTED; diff --git a/netwerk/base/nsILoadInfo.idl b/netwerk/base/nsILoadInfo.idl index 58c724f1072b7a..7c84f976ea52f0 100644 --- a/netwerk/base/nsILoadInfo.idl +++ b/netwerk/base/nsILoadInfo.idl @@ -432,6 +432,16 @@ interface nsILoadInfo : nsISupports */ [infallible] attribute unsigned long triggeringSandboxFlags; + + /** + * The window id and storage access status of the window of the + * context that triggered the load. This is used to allow self-initiated + * same-origin navigations to propogate their "has storage access" bit + * to the next Document. + */ + [infallible] attribute unsigned long long triggeringWindowId; + [infallible] attribute boolean triggeringStorageAccess; + /** * Allows to query only the security mode bits from above. */ diff --git a/netwerk/ipc/DocumentLoadListener.cpp b/netwerk/ipc/DocumentLoadListener.cpp index e465c421bc2891..cd363cacf1fe22 100644 --- a/netwerk/ipc/DocumentLoadListener.cpp +++ b/netwerk/ipc/DocumentLoadListener.cpp @@ -160,6 +160,8 @@ static auto CreateDocumentLoadInfo(CanonicalBrowsingContext* aBrowsingContext, } loadInfo->SetTriggeringSandboxFlags(aLoadState->TriggeringSandboxFlags()); + loadInfo->SetTriggeringWindowId(aLoadState->TriggeringWindowId()); + loadInfo->SetTriggeringStorageAccess(aLoadState->TriggeringStorageAccess()); loadInfo->SetHasValidUserGestureActivation( aLoadState->HasValidUserGestureActivation()); loadInfo->SetIsMetaRefresh(aLoadState->IsMetaRefresh()); @@ -187,6 +189,8 @@ static auto CreateObjectLoadInfo(nsDocShellLoadState* aLoadState, loadInfo->SetHasValidUserGestureActivation( aLoadState->HasValidUserGestureActivation()); loadInfo->SetTriggeringSandboxFlags(aLoadState->TriggeringSandboxFlags()); + loadInfo->SetTriggeringWindowId(aLoadState->TriggeringWindowId()); + loadInfo->SetTriggeringStorageAccess(aLoadState->TriggeringStorageAccess()); loadInfo->SetIsMetaRefresh(aLoadState->IsMetaRefresh()); return loadInfo.forget(); diff --git a/netwerk/ipc/NeckoChannelParams.ipdlh b/netwerk/ipc/NeckoChannelParams.ipdlh index 4283ab36171054..eeaa1bf02dac29 100644 --- a/netwerk/ipc/NeckoChannelParams.ipdlh +++ b/netwerk/ipc/NeckoChannelParams.ipdlh @@ -107,6 +107,8 @@ struct LoadInfoArgs uint32_t securityFlags; uint32_t sandboxFlags; uint32_t triggeringSandboxFlags; + uint64_t triggeringWindowId; + bool triggeringStorageAccess; nsContentPolicyType contentPolicyType; uint32_t tainting; bool blockAllMixedContent; @@ -238,6 +240,12 @@ struct ParentLoadInfoForwarderArgs // Sandbox Flags of the Document that triggered the load uint32_t triggeringSandboxFlags; + // Window ID and UsingStorageAccess of the Document that triggered the load. + // Used by the Storage Access API to determine if SubDocument loads should + // be partitioned or not. + uint64_t triggeringWindowId; + bool triggeringStorageAccess; + // We must also note that the tainting value was explicitly set // by the service worker. bool serviceWorkerTaintingSynthesized; diff --git a/toolkit/components/windowwatcher/nsWindowWatcher.cpp b/toolkit/components/windowwatcher/nsWindowWatcher.cpp index 8fe1543c0fd06e..a37d9eb18697c2 100644 --- a/toolkit/components/windowwatcher/nsWindowWatcher.cpp +++ b/toolkit/components/windowwatcher/nsWindowWatcher.cpp @@ -1279,6 +1279,12 @@ nsresult nsWindowWatcher::OpenWindowInternal( loadState->SetTriggeringSandboxFlags(parentBC->GetSandboxFlags()); } + if (parentInnerWin) { + loadState->SetTriggeringWindowId(parentInnerWin->WindowID()); + loadState->SetTriggeringStorageAccess( + parentInnerWin->HasStorageAccessPermissionGranted()); + } + if (subjectPrincipal) { loadState->SetTriggeringPrincipal(subjectPrincipal); }