зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1469993 - Grant storage access to a 3rd party, tracking resource if a opened document has user-interaction - part 1 - storing first user interaction in a document with an opener window, r=ehsan
This commit is contained in:
Родитель
6eb9f8c25b
Коммит
e6921e1adc
|
@ -515,41 +515,6 @@ EventListenerManagerHashClearEntry(PLDHashTable *table, PLDHashEntryHdr *entry)
|
|||
lm->~EventListenerManagerMapEntry();
|
||||
}
|
||||
|
||||
static bool
|
||||
IsThirdPartyWindowOrChannel(nsPIDOMWindowInner* aWindow,
|
||||
nsIChannel* aChannel,
|
||||
nsIURI* aURI)
|
||||
{
|
||||
MOZ_ASSERT(!aWindow || !aChannel,
|
||||
"A window and channel should not both be provided.");
|
||||
|
||||
nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil = services::GetThirdPartyUtil();
|
||||
if (!thirdPartyUtil) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// In the absence of a window or channel, we assume that we are first-party.
|
||||
bool thirdParty = false;
|
||||
|
||||
if (aWindow) {
|
||||
Unused << thirdPartyUtil->IsThirdPartyWindow(aWindow->GetOuterWindow(),
|
||||
aURI,
|
||||
&thirdParty);
|
||||
}
|
||||
|
||||
if (aChannel) {
|
||||
// Note, we must call IsThirdPartyChannel() here and not just try to
|
||||
// use nsILoadInfo.isThirdPartyContext. That nsILoadInfo property only
|
||||
// indicates if the parent loading window is third party or not. We
|
||||
// want to check the channel URI against the loading principal as well.
|
||||
Unused << thirdPartyUtil->IsThirdPartyChannel(aChannel,
|
||||
nullptr,
|
||||
&thirdParty);
|
||||
}
|
||||
|
||||
return thirdParty;
|
||||
}
|
||||
|
||||
class SameOriginCheckerImpl final : public nsIChannelEventSink,
|
||||
public nsIInterfaceRequestor
|
||||
{
|
||||
|
@ -8837,6 +8802,42 @@ nsContentUtils::GetCookieBehaviorForPrincipal(nsIPrincipal* aPrincipal,
|
|||
}
|
||||
}
|
||||
|
||||
// static public
|
||||
bool
|
||||
nsContentUtils::IsThirdPartyWindowOrChannel(nsPIDOMWindowInner* aWindow,
|
||||
nsIChannel* aChannel,
|
||||
nsIURI* aURI)
|
||||
{
|
||||
MOZ_ASSERT(!aWindow || !aChannel,
|
||||
"A window and channel should not both be provided.");
|
||||
|
||||
nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil = services::GetThirdPartyUtil();
|
||||
if (!thirdPartyUtil) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// In the absence of a window or channel, we assume that we are first-party.
|
||||
bool thirdParty = false;
|
||||
|
||||
if (aWindow) {
|
||||
Unused << thirdPartyUtil->IsThirdPartyWindow(aWindow->GetOuterWindow(),
|
||||
aURI,
|
||||
&thirdParty);
|
||||
}
|
||||
|
||||
if (aChannel) {
|
||||
// Note, we must call IsThirdPartyChannel() here and not just try to
|
||||
// use nsILoadInfo.isThirdPartyContext. That nsILoadInfo property only
|
||||
// indicates if the parent loading window is third party or not. We
|
||||
// want to check the channel URI against the loading principal as well.
|
||||
Unused << thirdPartyUtil->IsThirdPartyChannel(aChannel,
|
||||
nullptr,
|
||||
&thirdParty);
|
||||
}
|
||||
|
||||
return thirdParty;
|
||||
}
|
||||
|
||||
// static public
|
||||
bool
|
||||
nsContentUtils::StorageDisabledByAntiTracking(nsPIDOMWindowInner* aWindow,
|
||||
|
@ -8852,19 +8853,42 @@ nsContentUtils::StorageDisabledByAntiTracking(nsPIDOMWindowInner* aWindow,
|
|||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIChannel> channel;
|
||||
|
||||
// aChannel and aWindow are mutually exclusive.
|
||||
channel = aChannel;
|
||||
if (aWindow) {
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel;
|
||||
nsIDocument* document = aWindow->GetExtantDoc();
|
||||
if (document) {
|
||||
channel = document->GetChannel();
|
||||
httpChannel = do_QueryInterface(document->GetChannel());
|
||||
}
|
||||
|
||||
// If this is not a tracking resource, nothing is disabled.
|
||||
if (!httpChannel || !httpChannel->GetIsTrackingResource()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Maybe we want to grant this origin.
|
||||
nsIURI* documentURI = aURI ? aURI : aWindow->GetDocumentURI();
|
||||
if (documentURI &&
|
||||
nsGlobalWindowInner::Cast(aWindow)->IsFirstPartyStorageAccessGrantedFor(documentURI)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(channel);
|
||||
return httpChannel && httpChannel->GetIsTrackingResource();
|
||||
// aChannel and aWindow are mutually exclusive.
|
||||
MOZ_ASSERT(aChannel);
|
||||
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aChannel);
|
||||
if (!httpChannel) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!httpChannel->GetIsTrackingResource()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO storage access check
|
||||
return true;
|
||||
}
|
||||
|
||||
// static, private
|
||||
|
|
|
@ -2957,6 +2957,13 @@ public:
|
|||
nsIChannel* aChannel,
|
||||
nsIURI* aURI);
|
||||
|
||||
/*
|
||||
* Returns true if this window/channel is a 3rd party context.
|
||||
*/
|
||||
static bool IsThirdPartyWindowOrChannel(nsPIDOMWindowInner* aWindow,
|
||||
nsIChannel* aChannel,
|
||||
nsIURI* aURI);
|
||||
|
||||
/*
|
||||
* Serializes a HTML nsINode into its markup representation.
|
||||
*/
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/Likely.h"
|
||||
#include "mozilla/PresShell.h"
|
||||
#include "mozilla/StaticPrefs.h"
|
||||
#include "mozilla/URLExtraData.h"
|
||||
#include <algorithm>
|
||||
|
||||
|
@ -12415,10 +12416,62 @@ nsIDocument::NotifyUserGestureActivation()
|
|||
LogLevel::Debug,
|
||||
("Document %p has been activated by user.", this));
|
||||
doc->mUserGestureActivated = true;
|
||||
doc->MaybeAllowStorageForOpener();
|
||||
doc = doc->GetSameTypeParentDocument();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsIDocument::MaybeAllowStorageForOpener()
|
||||
{
|
||||
if (!StaticPrefs::privacy_restrict3rdpartystorage_enabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// This will probably change for project fission, but currently this document
|
||||
// and the opener are on the same process. In the future, we should make this
|
||||
// part async.
|
||||
|
||||
nsPIDOMWindowInner* inner = GetInnerWindow();
|
||||
if (NS_WARN_IF(!inner)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowOuter> outer = inner->GetOuterWindow();
|
||||
if (NS_WARN_IF(!outer)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowOuter> outerOpener = outer->GetOpener();
|
||||
if (NS_WARN_IF(!outerOpener)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsPIDOMWindowInner* openerInner = outerOpener->GetCurrentInnerWindow();
|
||||
if (NS_WARN_IF(!openerInner)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// No 3rd party.
|
||||
if (!nsContentUtils::IsThirdPartyWindowOrChannel(openerInner, nullptr,
|
||||
nullptr)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> uri = GetDocumentURI();
|
||||
if (NS_WARN_IF(!uri)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoString origin;
|
||||
nsresult rv = nsContentUtils::GetUTFOrigin(uri, origin);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsGlobalWindowInner::Cast(openerInner)->AddFirstPartyStorageAccessGrantedFor(origin);
|
||||
}
|
||||
|
||||
bool
|
||||
nsIDocument::HasBeenUserGestureActivated()
|
||||
{
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#if defined(MOZ_WIDGET_ANDROID)
|
||||
#include "mozilla/dom/WindowOrientationObserver.h"
|
||||
#endif
|
||||
#include "mozilla/StaticPrefs.h"
|
||||
#include "nsDOMOfflineResourceList.h"
|
||||
#include "nsError.h"
|
||||
#include "nsIIdleService.h"
|
||||
|
@ -8034,6 +8035,34 @@ nsGlobalWindowInner::GetRegionalPrefsLocales(nsTArray<nsString>& aLocales)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsGlobalWindowInner::AddFirstPartyStorageAccessGrantedFor(const nsAString& aOrigin)
|
||||
{
|
||||
MOZ_ASSERT(StaticPrefs::privacy_restrict3rdpartystorage_enabled());
|
||||
|
||||
if (mStorageGrantedOrigins.Contains(aOrigin)) {
|
||||
mStorageGrantedOrigins.AppendElement(aOrigin);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
nsGlobalWindowInner::IsFirstPartyStorageAccessGrantedFor(nsIURI* aURI) const
|
||||
{
|
||||
MOZ_ASSERT(aURI);
|
||||
|
||||
if (mStorageGrantedOrigins.IsEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsAutoString origin;
|
||||
nsresult rv = nsContentUtils::GetUTFOrigin(aURI, origin);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return mStorageGrantedOrigins.Contains(origin);
|
||||
}
|
||||
|
||||
IntlUtils*
|
||||
nsGlobalWindowInner::GetIntlUtils(ErrorResult& aError)
|
||||
{
|
||||
|
|
|
@ -717,6 +717,12 @@ public:
|
|||
mozilla::dom::IntlUtils*
|
||||
GetIntlUtils(mozilla::ErrorResult& aRv);
|
||||
|
||||
void
|
||||
AddFirstPartyStorageAccessGrantedFor(const nsAString& aOrigin);
|
||||
|
||||
bool
|
||||
IsFirstPartyStorageAccessGrantedFor(nsIURI* aURI) const;
|
||||
|
||||
public:
|
||||
void Alert(nsIPrincipal& aSubjectPrincipal,
|
||||
mozilla::ErrorResult& aError);
|
||||
|
@ -1476,6 +1482,8 @@ protected:
|
|||
|
||||
nsTArray<mozilla::UniquePtr<PromiseDocumentFlushedResolver>> mDocumentFlushedResolvers;
|
||||
|
||||
nsTArray<nsString> mStorageGrantedOrigins;
|
||||
|
||||
static InnerWindowByIdTable* sInnerWindowsById;
|
||||
|
||||
// Members in the mChromeFields member should only be used in chrome windows.
|
||||
|
|
|
@ -3682,6 +3682,8 @@ protected:
|
|||
// Return the same type parent docuement if exists, or return null.
|
||||
nsIDocument* GetSameTypeParentDocument();
|
||||
|
||||
void MaybeAllowStorageForOpener();
|
||||
|
||||
// Helpers for GetElementsByName.
|
||||
static bool MatchNameAttribute(mozilla::dom::Element* aElement,
|
||||
int32_t aNamespaceID,
|
||||
|
|
|
@ -142,9 +142,8 @@ ImageCacheKey::GetSpecialCaseDocumentToken(nsIDocument* aDocument, nsIURI* aURI)
|
|||
// If this document has been marked as tracker, let's use its address to make
|
||||
// a unique cache key.
|
||||
if (!pointer && aDocument &&
|
||||
nsContentUtils::StorageDisabledByAntiTracking(nullptr,
|
||||
aDocument->GetChannel(),
|
||||
aURI)) {
|
||||
nsContentUtils::StorageDisabledByAntiTracking(aDocument->GetInnerWindow(),
|
||||
nullptr, aURI)) {
|
||||
pointer = aDocument;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче