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);
}
bool WindowContext::CanSet(FieldIndex<IDX_UsingStorageAccess>,
const bool& aUsingStorageAccess,
ContentParent* aSource) {
return CheckOnlyOwningProcessCanSet(aSource);
}
bool WindowContext::CanSet(FieldIndex<IDX_ShouldResistFingerprinting>,
const bool& aShouldResistFingerprinting,
ContentParent* aSource) {

View File

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

View File

@ -18361,14 +18361,12 @@ nsICookieJarSettings* Document::CookieJarSettings() {
}
bool Document::UsingStorageAccess() {
// The HasStoragePermission flag in LoadInfo remains fixed when
// it is set in the parent process, so we need to check the cache
// to see if the permission is granted afterwards.
nsPIDOMWindowInner* inner = GetInnerWindow();
if (inner && inner->UsingStorageAccess()) {
return true;
if (WindowContext* wc = GetWindowContext()) {
return wc->GetUsingStorageAccess();
}
// 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) {
return false;
}

View File

@ -7644,12 +7644,22 @@ const nsIGlobalObject* nsPIDOMWindowInner::AsGlobal() const {
}
void nsPIDOMWindowInner::SaveStorageAccessPermissionGranted() {
mUsingStorageAccess = true;
WindowContext* wc = GetWindowContext();
if (wc) {
Unused << wc->SetUsingStorageAccess(true);
}
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,
WindowGlobalChild* aActor)
@ -7674,7 +7684,6 @@ nsPIDOMWindowInner::nsPIDOMWindowInner(nsPIDOMWindowOuter* aOuterWindow,
mNumOfIndexedDBDatabases(0),
mNumOfOpenWebSockets(0),
mEvent(nullptr),
mUsingStorageAccess(false),
mWindowGlobalChild(aActor),
mWasSuspendedByGroup(false) {
MOZ_ASSERT(aOuterWindow);

View File

@ -760,10 +760,6 @@ class nsPIDOMWindowInner : public mozIDOMWindow {
// the event object alive.
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.
//
// 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());
fields.Get<Indexes::IDX_IsOriginalFrameSource>() =
loadInfo->GetOriginalFrameSrcLoad();
fields.Get<Indexes::IDX_UsingStorageAccess>() =
loadInfo->GetStoragePermission() != nsILoadInfo::NoStoragePermission;
channel->GetSecurityInfo(getter_AddRefs(securityInfo));
}

View File

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

View File

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