Bug 1635050 - Implement a whitelist system for cookieBehavior REJECT_FOREIGN with exceptions, r=dimi

Differential Revision: https://phabricator.services.mozilla.com/D73615
This commit is contained in:
Andrea Marchesini 2020-05-05 14:34:34 +00:00
Родитель a44d97ff35
Коммит c3a7e58828
4 изменённых файлов: 153 добавлений и 0 удалений

Просмотреть файл

@ -31,6 +31,7 @@
#include "nsIOService.h" #include "nsIOService.h"
#include "nsIWebProgressListener.h" #include "nsIWebProgressListener.h"
#include "nsScriptSecurityManager.h" #include "nsScriptSecurityManager.h"
#include "RejectForeignAllowList.h"
namespace mozilla { namespace mozilla {
@ -960,6 +961,11 @@ bool ContentBlocking::ShouldAllowAccessFor(nsPIDOMWindowInner* aWindow,
} }
} else { } else {
MOZ_ASSERT(CookieJarSettings::IsRejectThirdPartyWithExceptions(behavior)); MOZ_ASSERT(CookieJarSettings::IsRejectThirdPartyWithExceptions(behavior));
if (RejectForeignAllowList::Check(document)) {
LOG(("This window is whitelisted for reject foreign"));
return true;
}
blockedReason = nsIWebProgressListener::STATE_COOKIES_PARTITIONED_FOREIGN; blockedReason = nsIWebProgressListener::STATE_COOKIES_PARTITIONED_FOREIGN;
} }
@ -1166,6 +1172,10 @@ bool ContentBlocking::ShouldAllowAccessFor(nsIChannel* aChannel, nsIURI* aURI,
} }
} else { } else {
MOZ_ASSERT(CookieJarSettings::IsRejectThirdPartyWithExceptions(behavior)); MOZ_ASSERT(CookieJarSettings::IsRejectThirdPartyWithExceptions(behavior));
if (httpChannel && RejectForeignAllowList::Check(httpChannel)) {
LOG(("This channel is whitelisted"));
return true;
}
blockedReason = nsIWebProgressListener::STATE_COOKIES_BLOCKED_FOREIGN; blockedReason = nsIWebProgressListener::STATE_COOKIES_BLOCKED_FOREIGN;
} }

Просмотреть файл

@ -0,0 +1,100 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "RejectForeignAllowList.h"
#include "mozilla/dom/Document.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/StaticPtr.h"
#include "nsNetUtil.h"
#define REJECTFOREIGNALLOWLIST_PREF \
NS_LITERAL_CSTRING("urlclassifier.trackingAnnotationSkipURLs")
#define REJECTFOREIGNALLOWLIST_NAME NS_LITERAL_CSTRING("RejectForeignAllowList")
namespace mozilla {
namespace {
StaticRefPtr<RejectForeignAllowList> gRejectForeignAllowList;
} // namespace
// static
bool RejectForeignAllowList::Check(dom::Document* aDocument) {
MOZ_ASSERT(aDocument);
nsIURI* documentURI = aDocument->GetDocumentURI();
if (!documentURI) {
return false;
}
return GetOrCreate()->CheckInternal(documentURI);
}
// static
bool RejectForeignAllowList::Check(nsIHttpChannel* aChannel) {
MOZ_ASSERT(aChannel);
nsCOMPtr<nsIURI> channelURI;
nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(channelURI));
if (NS_WARN_IF(NS_FAILED(rv))) {
return false;
}
return GetOrCreate()->CheckInternal(channelURI);
}
// static
RejectForeignAllowList* RejectForeignAllowList::GetOrCreate() {
if (!gRejectForeignAllowList) {
gRejectForeignAllowList = new RejectForeignAllowList();
nsCOMPtr<nsIUrlClassifierSkipListService> skipListService =
do_GetService("@mozilla.org/url-classifier/skip-list-service;1");
if (skipListService) {
skipListService->RegisterAndRunSkipListObserver(
REJECTFOREIGNALLOWLIST_NAME, REJECTFOREIGNALLOWLIST_PREF,
gRejectForeignAllowList);
}
RunOnShutdown([skipListService] {
if (gRejectForeignAllowList) {
if (skipListService) {
skipListService->UnregisterSkipListObserver(
REJECTFOREIGNALLOWLIST_NAME, gRejectForeignAllowList);
}
gRejectForeignAllowList = nullptr;
}
});
}
return gRejectForeignAllowList;
}
bool RejectForeignAllowList::CheckInternal(nsIURI* aURI) {
MOZ_ASSERT(aURI);
return nsContentUtils::IsURIInList(aURI, mList);
}
NS_IMETHODIMP
RejectForeignAllowList::OnSkipListUpdate(const nsACString& aList) {
mList = aList;
return NS_OK;
}
RejectForeignAllowList::RejectForeignAllowList() = default;
RejectForeignAllowList::~RejectForeignAllowList() = default;
NS_INTERFACE_MAP_BEGIN(RejectForeignAllowList)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports,
nsIUrlClassifierSkipListObserver)
NS_INTERFACE_MAP_ENTRY(nsIUrlClassifierSkipListObserver)
NS_INTERFACE_MAP_END
NS_IMPL_ADDREF(RejectForeignAllowList)
NS_IMPL_RELEASE(RejectForeignAllowList)
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,42 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_RejectForeignAllowList_h
#define mozilla_RejectForeignAllowList_h
#include "nsIUrlClassifierSkipListService.h"
class nsIHttpChannel;
class nsIURI;
namespace mozilla {
namespace dom {
class Document;
}
class RejectForeignAllowList final : public nsIUrlClassifierSkipListObserver {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIURLCLASSIFIERSKIPLISTOBSERVER
static bool Check(dom::Document* aDocument);
static bool Check(nsIHttpChannel* aChannel);
private:
static RejectForeignAllowList* GetOrCreate();
RejectForeignAllowList();
~RejectForeignAllowList();
bool CheckInternal(nsIURI* aURI);
nsCString mList;
};
} // namespace mozilla
#endif // mozilla_RejectForeignAllowList_h

Просмотреть файл

@ -54,6 +54,7 @@ UNIFIED_SOURCES += [
'ContentBlockingNotifier.cpp', 'ContentBlockingNotifier.cpp',
'ContentBlockingUserInteraction.cpp', 'ContentBlockingUserInteraction.cpp',
'DynamicFpiRedirectHeuristic.cpp', 'DynamicFpiRedirectHeuristic.cpp',
'RejectForeignAllowList.cpp',
'SettingsChangeObserver.cpp', 'SettingsChangeObserver.cpp',
'StorageAccess.cpp', 'StorageAccess.cpp',
'StoragePrincipalHelper.cpp', 'StoragePrincipalHelper.cpp',