Bug 1848783, part 5 - Move UsingStorageAccess onto the WindowContext to fix the storage access check for resource reuqests within subdocuments without active storage access but with permission r=timhuang,nika

Differential Revision: https://phabricator.services.mozilla.com/D187138
This commit is contained in:
Benjamin VanderSloot 2023-09-19 21:03:08 +00:00
parent e83a883573
commit 4297663528
8 changed files with 44 additions and 26 deletions

View File

@ -228,6 +228,12 @@ bool WindowContext::CanSet(FieldIndex<IDX_IsThirdPartyTrackingResourceWindow>,
return CheckOnlyOwningProcessCanSet(aSource); return CheckOnlyOwningProcessCanSet(aSource);
} }
bool WindowContext::CanSet(FieldIndex<IDX_UsingStorageAccess>,
const bool& aUsingStorageAccess,
ContentParent* aSource) {
return CheckOnlyOwningProcessCanSet(aSource);
}
bool WindowContext::CanSet(FieldIndex<IDX_ShouldResistFingerprinting>, bool WindowContext::CanSet(FieldIndex<IDX_ShouldResistFingerprinting>,
const bool& aShouldResistFingerprinting, const bool& aShouldResistFingerprinting,
ContentParent* aSource) { ContentParent* aSource) {

View File

@ -51,6 +51,9 @@ class BrowsingContextGroup;
/* Whether this window's channel has been marked as a third-party \ /* Whether this window's channel has been marked as a third-party \
* tracking resource */ \ * tracking resource */ \
FIELD(IsThirdPartyTrackingResourceWindow, bool) \ FIELD(IsThirdPartyTrackingResourceWindow, bool) \
/* Whether this window is using its unpartitioned cookies due to \
* the Storage Access API */ \
FIELD(UsingStorageAccess, bool) \
FIELD(ShouldResistFingerprinting, bool) \ FIELD(ShouldResistFingerprinting, bool) \
FIELD(IsSecureContext, bool) \ FIELD(IsSecureContext, bool) \
FIELD(IsOriginalFrameSource, bool) \ FIELD(IsOriginalFrameSource, bool) \
@ -266,6 +269,8 @@ class WindowContext : public nsISupports, public nsWrapperCache {
bool CanSet(FieldIndex<IDX_IsThirdPartyTrackingResourceWindow>, bool CanSet(FieldIndex<IDX_IsThirdPartyTrackingResourceWindow>,
const bool& aIsThirdPartyTrackingResourceWindow, const bool& aIsThirdPartyTrackingResourceWindow,
ContentParent* aSource); ContentParent* aSource);
bool CanSet(FieldIndex<IDX_UsingStorageAccess>,
const bool& aUsingStorageAccess, ContentParent* aSource);
bool CanSet(FieldIndex<IDX_ShouldResistFingerprinting>, bool CanSet(FieldIndex<IDX_ShouldResistFingerprinting>,
const bool& aShouldResistFingerprinting, ContentParent* aSource); const bool& aShouldResistFingerprinting, ContentParent* aSource);
bool CanSet(FieldIndex<IDX_IsSecureContext>, const bool& aIsSecureContext, bool CanSet(FieldIndex<IDX_IsSecureContext>, const bool& aIsSecureContext,

View File

@ -18361,14 +18361,12 @@ nsICookieJarSettings* Document::CookieJarSettings() {
} }
bool Document::UsingStorageAccess() { bool Document::UsingStorageAccess() {
// The HasStoragePermission flag in LoadInfo remains fixed when if (WindowContext* wc = GetWindowContext()) {
// it is set in the parent process, so we need to check the cache return wc->GetUsingStorageAccess();
// to see if the permission is granted afterwards.
nsPIDOMWindowInner* inner = GetInnerWindow();
if (inner && inner->UsingStorageAccess()) {
return true;
} }
// If we don't yet have a window context, we have to use the decision
// from the Document's Channel's LoadInfo directly.
if (!mChannel) { if (!mChannel) {
return false; return false;
} }

View File

@ -7644,12 +7644,22 @@ const nsIGlobalObject* nsPIDOMWindowInner::AsGlobal() const {
} }
void nsPIDOMWindowInner::SaveStorageAccessPermissionGranted() { void nsPIDOMWindowInner::SaveStorageAccessPermissionGranted() {
mUsingStorageAccess = true; WindowContext* wc = GetWindowContext();
if (wc) {
Unused << wc->SetUsingStorageAccess(true);
}
nsGlobalWindowInner::Cast(this)->StorageAccessPermissionGranted(); nsGlobalWindowInner::Cast(this)->StorageAccessPermissionGranted();
} }
bool nsPIDOMWindowInner::UsingStorageAccess() { return mUsingStorageAccess; } bool nsPIDOMWindowInner::UsingStorageAccess() {
WindowContext* wc = GetWindowContext();
if (!wc) {
return false;
}
return wc->GetUsingStorageAccess();
}
nsPIDOMWindowInner::nsPIDOMWindowInner(nsPIDOMWindowOuter* aOuterWindow, nsPIDOMWindowInner::nsPIDOMWindowInner(nsPIDOMWindowOuter* aOuterWindow,
WindowGlobalChild* aActor) WindowGlobalChild* aActor)
@ -7674,7 +7684,6 @@ nsPIDOMWindowInner::nsPIDOMWindowInner(nsPIDOMWindowOuter* aOuterWindow,
mNumOfIndexedDBDatabases(0), mNumOfIndexedDBDatabases(0),
mNumOfOpenWebSockets(0), mNumOfOpenWebSockets(0),
mEvent(nullptr), mEvent(nullptr),
mUsingStorageAccess(false),
mWindowGlobalChild(aActor), mWindowGlobalChild(aActor),
mWasSuspendedByGroup(false) { mWasSuspendedByGroup(false) {
MOZ_ASSERT(aOuterWindow); MOZ_ASSERT(aOuterWindow);

View File

@ -760,10 +760,6 @@ class nsPIDOMWindowInner : public mozIDOMWindow {
// the event object alive. // the event object alive.
mozilla::dom::Event* mEvent; mozilla::dom::Event* mEvent;
// A boolean flag indicating whether storage access is granted for the
// current window and that it is currently being used by this window.
bool mUsingStorageAccess;
// The WindowGlobalChild actor for this window. // The WindowGlobalChild actor for this window.
// //
// This will be non-null during the full lifetime of the window, initialized // This will be non-null during the full lifetime of the window, initialized

View File

@ -150,6 +150,8 @@ WindowGlobalInit WindowGlobalActor::WindowInitializer(
nsCOMPtr<nsILoadInfo> loadInfo(channel->LoadInfo()); nsCOMPtr<nsILoadInfo> loadInfo(channel->LoadInfo());
fields.Get<Indexes::IDX_IsOriginalFrameSource>() = fields.Get<Indexes::IDX_IsOriginalFrameSource>() =
loadInfo->GetOriginalFrameSrcLoad(); loadInfo->GetOriginalFrameSrcLoad();
fields.Get<Indexes::IDX_UsingStorageAccess>() =
loadInfo->GetStoragePermission() != nsILoadInfo::NoStoragePermission;
channel->GetSecurityInfo(getter_AddRefs(securityInfo)); channel->GetSecurityInfo(getter_AddRefs(securityInfo));
} }

View File

@ -219,6 +219,8 @@ void WindowGlobalChild::OnNewDocument(Document* aDocument) {
if (nsCOMPtr<nsIChannel> channel = aDocument->GetChannel()) { if (nsCOMPtr<nsIChannel> channel = aDocument->GetChannel()) {
nsCOMPtr<nsILoadInfo> loadInfo(channel->LoadInfo()); nsCOMPtr<nsILoadInfo> loadInfo(channel->LoadInfo());
txn.SetIsOriginalFrameSource(loadInfo->GetOriginalFrameSrcLoad()); txn.SetIsOriginalFrameSource(loadInfo->GetOriginalFrameSrcLoad());
txn.SetUsingStorageAccess(loadInfo->GetStoragePermission() !=
nsILoadInfo::NoStoragePermission);
} else { } else {
txn.SetIsOriginalFrameSource(false); txn.SetIsOriginalFrameSource(false);
} }

View File

@ -557,23 +557,23 @@ AntiTrackingUtils::GetStoragePermissionStateInParent(nsIChannel* aChannel) {
return nsILoadInfo::HasStoragePermission; return nsILoadInfo::HasStoragePermission;
} }
} else if (!bc->IsTop()) { } else if (!bc->IsTop()) {
// Only check the frame only permission if the channel is not in the top // For subframe resources, check if the document has storage access
// browsing context. // and that the resource being loaded is same-site to the page.
RefPtr<nsEffectiveTLDService> etld = nsEffectiveTLDService::GetInstance(); WindowContext* wc = bc->GetCurrentWindowContext();
if (!etld) { if (!wc) {
return nsILoadInfo::NoStoragePermission; return nsILoadInfo::NoStoragePermission;
} }
nsCString trackingSite; WindowGlobalParent* wgp = wc->Canonical();
rv = etld->GetSite(trackingURI, trackingSite); if (!wgp) {
if (NS_WARN_IF(NS_FAILED(rv))) {
return nsILoadInfo::NoStoragePermission; return nsILoadInfo::NoStoragePermission;
} }
nsAutoCString type; nsIPrincipal* framePrincipal = wgp->DocumentPrincipal();
AntiTrackingUtils::CreateStorageFramePermissionKey(trackingSite, type); if (!framePrincipal) {
return nsILoadInfo::NoStoragePermission;
if (AntiTrackingUtils::CheckStoragePermission( }
targetPrincipal, type, NS_UsePrivateBrowsing(aChannel), bool isThirdParty = true;
&unusedReason, unusedReason)) { nsresult rv = framePrincipal->IsThirdPartyURI(trackingURI, &isThirdParty);
if (NS_SUCCEEDED(rv) && wc->GetUsingStorageAccess() && !isThirdParty) {
return nsILoadInfo::HasStoragePermission; return nsILoadInfo::HasStoragePermission;
} }
} }