зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1498370 - Update the storage access flag when storage access is granted/denied r=baku
Differential Revision: https://phabricator.services.mozilla.com/D8550 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
8e9e5f75ac
Коммит
ecd5aada04
|
@ -13669,31 +13669,6 @@ nsIDocument::HasStorageAccess(mozilla::ErrorResult& aRv)
|
|||
return promise.forget();
|
||||
}
|
||||
|
||||
if (AntiTrackingCommon::ShouldHonorContentBlockingCookieRestrictions() &&
|
||||
StaticPrefs::network_cookie_cookieBehavior() ==
|
||||
nsICookieService::BEHAVIOR_REJECT_TRACKER) {
|
||||
// If we need to abide by Content Blocking cookie restrictions, ensure to
|
||||
// first do all of our storage access checks. If storage access isn't
|
||||
// disabled in our document, given that we're a third-party, we must either
|
||||
// not be a tracker, or be whitelisted for some reason (e.g. a storage
|
||||
// access permission being granted). In that case, resolve the promise and
|
||||
// say we have obtained storage access.
|
||||
if (!nsContentUtils::StorageDisabledByAntiTracking(this, nullptr)) {
|
||||
// Note, storage might be allowed because the top-level document is on
|
||||
// the content blocking allowlist! In that case, don't provide special
|
||||
// treatment here.
|
||||
bool isOnAllowList = false;
|
||||
if (NS_SUCCEEDED(AntiTrackingCommon::IsOnContentBlockingAllowList(
|
||||
topLevelDoc->GetDocumentURI(),
|
||||
AntiTrackingCommon::eStorageChecks,
|
||||
isOnAllowList)) &&
|
||||
!isOnAllowList) {
|
||||
promise->MaybeResolve(true);
|
||||
return promise.forget();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsPIDOMWindowInner* inner = GetInnerWindow();
|
||||
nsGlobalWindowOuter* outer = nullptr;
|
||||
if (inner) {
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
#include "nsDOMNavigationTiming.h"
|
||||
#include "nsICookieService.h"
|
||||
#include "nsIDOMStorageManager.h"
|
||||
#include "nsIPermission.h"
|
||||
#include "nsIPermissionManager.h"
|
||||
#include "nsISecureBrowserUI.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
#include "mozilla/AntiTrackingCommon.h"
|
||||
|
@ -978,6 +980,11 @@ nsGlobalWindowOuter::~nsGlobalWindowOuter()
|
|||
if (ac)
|
||||
ac->RemoveWindowAsListener(this);
|
||||
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
if (obs) {
|
||||
obs->RemoveObserver(this, PERM_CHANGE_NOTIFICATION);
|
||||
}
|
||||
|
||||
nsLayoutStatics::Release();
|
||||
}
|
||||
|
||||
|
@ -1089,6 +1096,7 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsGlobalWindowOuter)
|
|||
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIDOMChromeWindow, IsChromeWindow())
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIObserver)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
|
||||
|
@ -6802,6 +6810,56 @@ nsGlobalWindowOuter::GetInterface(const nsIID & aIID, void **aSink)
|
|||
return rv;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// nsGlobalWindowOuter::nsIObserver
|
||||
//*****************************************************************************
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGlobalWindowOuter::Observe(nsISupports* aSupports, const char* aTopic,
|
||||
const char16_t* aData)
|
||||
{
|
||||
if (!nsCRT::strcmp(aTopic, PERM_CHANGE_NOTIFICATION)) {
|
||||
if (!nsCRT::strcmp(aData, u"cleared") && !aSupports) {
|
||||
// All permissions have been cleared.
|
||||
mHasStorageAccess = false;
|
||||
return NS_OK;
|
||||
}
|
||||
nsCOMPtr<nsIPermission> permission = do_QueryInterface(aSupports);
|
||||
if (!permission) {
|
||||
return NS_OK;
|
||||
}
|
||||
nsIPrincipal* principal = GetPrincipal();
|
||||
if (!principal) {
|
||||
return NS_OK;
|
||||
}
|
||||
if (!AntiTrackingCommon::IsStorageAccessPermission(permission, principal)) {
|
||||
return NS_OK;
|
||||
}
|
||||
if (!nsCRT::strcmp(aData, u"deleted")) {
|
||||
// The storage access permission was deleted.
|
||||
mHasStorageAccess = false;
|
||||
return NS_OK;
|
||||
}
|
||||
if (!nsCRT::strcmp(aData, u"added") ||
|
||||
!nsCRT::strcmp(aData, u"changed")) {
|
||||
// The storage access permission was granted or modified.
|
||||
uint32_t expireType = 0;
|
||||
int64_t expireTime = 0;
|
||||
MOZ_ALWAYS_SUCCEEDS(permission->GetExpireType(&expireType));
|
||||
MOZ_ALWAYS_SUCCEEDS(permission->GetExpireTime(&expireTime));
|
||||
if ((expireType == nsIPermissionManager::EXPIRE_TIME &&
|
||||
expireTime >= PR_Now() / 1000) ||
|
||||
(expireType == nsIPermissionManager::EXPIRE_SESSION &&
|
||||
expireTime != 0)) {
|
||||
// Permission hasn't expired yet.
|
||||
mHasStorageAccess = true;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
nsGlobalWindowOuter::IsSuspended() const
|
||||
{
|
||||
|
@ -7673,6 +7731,10 @@ nsGlobalWindowOuter::Create(nsIDocShell* aDocShell, bool aIsChrome)
|
|||
window->SetDocShell(aDocShell);
|
||||
|
||||
window->InitWasOffline();
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
if (obs) {
|
||||
obs->AddObserver(window, PERM_CHANGE_NOTIFICATION, true);
|
||||
}
|
||||
return window.forget();
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "nsIBrowserDOMWindow.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIDOMChromeWindow.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
#include "nsIScriptObjectPrincipal.h"
|
||||
#include "nsITimer.h"
|
||||
|
@ -172,6 +173,7 @@ class nsGlobalWindowOuter final
|
|||
, public nsSupportsWeakReference
|
||||
, public nsIInterfaceRequestor
|
||||
, public PRCListStr
|
||||
, public nsIObserver
|
||||
{
|
||||
public:
|
||||
typedef nsDataHashtable<nsUint64HashKey, nsGlobalWindowOuter*> OuterWindowByIdTable;
|
||||
|
@ -361,6 +363,9 @@ public:
|
|||
// nsIInterfaceRequestor
|
||||
NS_DECL_NSIINTERFACEREQUESTOR
|
||||
|
||||
// nsIObserver
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
already_AddRefed<nsPIDOMWindowOuter> IndexedGetterOuter(uint32_t aIndex);
|
||||
|
||||
already_AddRefed<nsPIDOMWindowOuter> GetTop() override;
|
||||
|
|
|
@ -564,6 +564,42 @@ AntiTrackingCommon::SaveFirstPartyStorageAccessGrantedForOriginOnParentProcess(n
|
|||
LOG(("Result: %s", NS_SUCCEEDED(rv) ? "success" : "failure"));
|
||||
}
|
||||
|
||||
// static
|
||||
bool
|
||||
AntiTrackingCommon::IsStorageAccessPermission(nsIPermission* aPermission,
|
||||
nsIPrincipal* aPrincipal)
|
||||
{
|
||||
MOZ_ASSERT(aPermission);
|
||||
MOZ_ASSERT(aPrincipal);
|
||||
|
||||
nsAutoCString origin;
|
||||
nsresult rv = aPrincipal->GetOriginNoSuffix(origin);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// The permission key may belong either to a tracking origin on the same
|
||||
// origin as the granted origin, or on another origin as the granted origin
|
||||
// (for example when a tracker in a third-party context uses window.open to
|
||||
// open another origin where that second origin would be the granted origin.)
|
||||
// But even in the second case, the type of the permission would still be
|
||||
// formed by concatenating the granted origin to the end of the type name
|
||||
// (see CreatePermissionKey). Therefore, we pass in the same argument to
|
||||
// both tracking origin and granted origin here in order to compute the
|
||||
// shorter permission key and will then do a prefix match on the type of the
|
||||
// input permission to see if it is a storage access permission or not.
|
||||
nsAutoCString permissionKey;
|
||||
CreatePermissionKey(origin, origin, permissionKey);
|
||||
|
||||
nsAutoCString type;
|
||||
rv = aPermission->GetType(type);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return StringBeginsWith(type, permissionKey);
|
||||
}
|
||||
|
||||
bool
|
||||
AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor(nsPIDOMWindowInner* aWindow,
|
||||
nsIURI* aURI,
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
class nsIChannel;
|
||||
class nsIHttpChannel;
|
||||
class nsIPermission;
|
||||
class nsIPrincipal;
|
||||
class nsIURI;
|
||||
class nsPIDOMWindowInner;
|
||||
|
@ -108,6 +109,11 @@ public:
|
|||
nsPIDOMWindowInner* aParentWindow,
|
||||
StorageAccessGrantedReason aReason);
|
||||
|
||||
// Returns true if the permission passed in is a storage access permission
|
||||
// for the passed in principal argument.
|
||||
static bool
|
||||
IsStorageAccessPermission(nsIPermission* aPermission, nsIPrincipal* aPrincipal);
|
||||
|
||||
static void
|
||||
StoreUserInteractionFor(nsIPrincipal* aPrincipal);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче