зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1620322 - Part 2: Refactor the code for content blocking events and notifications out of AntiTrackingCommon.cpp; r=baku
Differential Revision: https://phabricator.services.mozilla.com/D65743 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
da8e27212f
Коммит
4bc71d0112
|
@ -110,7 +110,7 @@ static void ReportOriginSingleHash(OriginMetricID aId,
|
|||
|
||||
Maybe<uint32_t> ContentBlockingLog::RecordLogParent(
|
||||
const nsACString& aOrigin, uint32_t aType, bool aBlocked,
|
||||
const Maybe<AntiTrackingCommon::StorageAccessGrantedReason>& aReason,
|
||||
const Maybe<ContentBlockingNotifier::StorageAccessGrantedReason>& aReason,
|
||||
const nsTArray<nsCString>& aTrackingFullHashes) {
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#ifndef mozilla_dom_ContentBlockingLog_h
|
||||
#define mozilla_dom_ContentBlockingLog_h
|
||||
|
||||
#include "mozilla/AntiTrackingCommon.h"
|
||||
#include "mozilla/ContentBlockingNotifier.h"
|
||||
#include "mozilla/JSONWriter.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/StaticPrefs_browser.h"
|
||||
|
@ -18,18 +18,20 @@
|
|||
#include "nsTArray.h"
|
||||
#include "nsWindowSizes.h"
|
||||
|
||||
class nsIPrincipal;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class ContentBlockingLog final {
|
||||
typedef AntiTrackingCommon::StorageAccessGrantedReason
|
||||
typedef ContentBlockingNotifier::StorageAccessGrantedReason
|
||||
StorageAccessGrantedReason;
|
||||
|
||||
struct LogEntry {
|
||||
uint32_t mType;
|
||||
uint32_t mRepeatCount;
|
||||
bool mBlocked;
|
||||
Maybe<AntiTrackingCommon::StorageAccessGrantedReason> mReason;
|
||||
Maybe<ContentBlockingNotifier::StorageAccessGrantedReason> mReason;
|
||||
nsTArray<nsCString> mTrackingFullHashes;
|
||||
};
|
||||
|
||||
|
@ -87,12 +89,12 @@ class ContentBlockingLog final {
|
|||
// ContentBlockingLog from content processes.
|
||||
Maybe<uint32_t> RecordLogParent(
|
||||
const nsACString& aOrigin, uint32_t aType, bool aBlocked,
|
||||
const Maybe<AntiTrackingCommon::StorageAccessGrantedReason>& aReason,
|
||||
const Maybe<ContentBlockingNotifier::StorageAccessGrantedReason>& aReason,
|
||||
const nsTArray<nsCString>& aTrackingFullHashes);
|
||||
|
||||
void RecordLog(
|
||||
const nsACString& aOrigin, uint32_t aType, bool aBlocked,
|
||||
const Maybe<AntiTrackingCommon::StorageAccessGrantedReason>& aReason,
|
||||
const Maybe<ContentBlockingNotifier::StorageAccessGrantedReason>& aReason,
|
||||
const nsTArray<nsCString>& aTrackingFullHashes) {
|
||||
RecordLogInternal(aOrigin, aType, aBlocked, aReason, aTrackingFullHashes);
|
||||
}
|
||||
|
@ -241,8 +243,8 @@ class ContentBlockingLog final {
|
|||
private:
|
||||
void RecordLogInternal(
|
||||
const nsACString& aOrigin, uint32_t aType, bool aBlocked,
|
||||
const Maybe<AntiTrackingCommon::StorageAccessGrantedReason>& aReason =
|
||||
Nothing(),
|
||||
const Maybe<ContentBlockingNotifier::StorageAccessGrantedReason>&
|
||||
aReason = Nothing(),
|
||||
const nsTArray<nsCString>& aTrackingFullHashes = nsTArray<nsCString>()) {
|
||||
DebugOnly<bool> isCookiesBlockedTracker =
|
||||
aType == nsIWebProgressListener::STATE_COOKIES_BLOCKED_TRACKER ||
|
||||
|
|
|
@ -15066,7 +15066,7 @@ void Document::MaybeAllowStorageForOpenerAfterUserInteraction() {
|
|||
// We don't care when the asynchronous work finishes here.
|
||||
Unused << AntiTrackingCommon::AddFirstPartyStorageAccessGrantedFor(
|
||||
NodePrincipal(), openerInner,
|
||||
AntiTrackingCommon::eOpenerAfterUserInteraction);
|
||||
ContentBlockingNotifier::eOpenerAfterUserInteraction);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
@ -15721,7 +15721,7 @@ already_AddRefed<mozilla::dom::Promise> Document::RequestStorageAccess(
|
|||
return std::move(p);
|
||||
};
|
||||
AntiTrackingCommon::AddFirstPartyStorageAccessGrantedFor(
|
||||
NodePrincipal(), inner, AntiTrackingCommon::eStorageAccessAPI,
|
||||
NodePrincipal(), inner, ContentBlockingNotifier::eStorageAccessAPI,
|
||||
performFinalChecks)
|
||||
->Then(
|
||||
GetCurrentThreadSerialEventTarget(), __func__,
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "nsPluginArray.h"
|
||||
#include "nsMimeTypeArray.h"
|
||||
#include "mozilla/AntiTrackingCommon.h"
|
||||
#include "mozilla/ContentBlockingNotifier.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/dom/BodyExtractor.h"
|
||||
#include "mozilla/dom/FetchBinding.h"
|
||||
|
@ -530,10 +531,10 @@ bool Navigator::CookieEnabled() {
|
|||
bool granted = AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor(
|
||||
mWindow, contentURI, &rejectedReason);
|
||||
|
||||
AntiTrackingCommon::NotifyBlockingDecision(
|
||||
ContentBlockingNotifier::OnDecision(
|
||||
mWindow,
|
||||
granted ? AntiTrackingCommon::BlockingDecision::eAllow
|
||||
: AntiTrackingCommon::BlockingDecision::eBlock,
|
||||
granted ? ContentBlockingNotifier::BlockingDecision::eAllow
|
||||
: ContentBlockingNotifier::BlockingDecision::eBlock,
|
||||
rejectedReason);
|
||||
return granted;
|
||||
}
|
||||
|
|
|
@ -500,8 +500,8 @@ ThirdPartyUtil::AnalyzeChannel(nsIChannel* aChannel, bool aNotify, nsIURI* aURI,
|
|||
|
||||
if (aNotify && !result.contains(
|
||||
ThirdPartyAnalysis::IsFirstPartyStorageAccessGranted)) {
|
||||
AntiTrackingCommon::NotifyBlockingDecision(
|
||||
aChannel, AntiTrackingCommon::BlockingDecision::eBlock,
|
||||
ContentBlockingNotifier::OnDecision(
|
||||
aChannel, ContentBlockingNotifier::BlockingDecision::eBlock,
|
||||
*aRejectedReason);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7184,7 +7184,7 @@ void nsGlobalWindowOuter::MaybeAllowStorageForOpenedWindow(nsIURI* aURI) {
|
|||
|
||||
// We don't care when the asynchronous work finishes here.
|
||||
Unused << AntiTrackingCommon::AddFirstPartyStorageAccessGrantedFor(
|
||||
principal, inner, AntiTrackingCommon::eOpener);
|
||||
principal, inner, ContentBlockingNotifier::eOpener);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
|
|
|
@ -4048,7 +4048,7 @@ void BrowserChild::NotifyContentBlockingEvent(
|
|||
uint32_t aEvent, nsIChannel* aChannel, bool aBlocked,
|
||||
const nsACString& aTrackingOrigin,
|
||||
const nsTArray<nsCString>& aTrackingFullHashes,
|
||||
const Maybe<mozilla::AntiTrackingCommon::StorageAccessGrantedReason>&
|
||||
const Maybe<mozilla::ContentBlockingNotifier::StorageAccessGrantedReason>&
|
||||
aReason) {
|
||||
if (!IPCOpen()) {
|
||||
return;
|
||||
|
|
|
@ -699,7 +699,8 @@ class BrowserChild final : public nsMessageManagerScriptExecutor,
|
|||
uint32_t aEvent, nsIChannel* aChannel, bool aBlocked,
|
||||
const nsACString& aTrackingOrigin,
|
||||
const nsTArray<nsCString>& aTrackingFullHashes,
|
||||
const Maybe<AntiTrackingCommon::StorageAccessGrantedReason>& aReason);
|
||||
const Maybe<ContentBlockingNotifier::StorageAccessGrantedReason>&
|
||||
aReason);
|
||||
|
||||
protected:
|
||||
virtual ~BrowserChild();
|
||||
|
|
|
@ -2695,7 +2695,7 @@ mozilla::ipc::IPCResult BrowserParent::RecvNotifyContentBlockingEvent(
|
|||
const uint32_t& aEvent, const RequestData& aRequestData,
|
||||
const bool aBlocked, const nsACString& aTrackingOrigin,
|
||||
nsTArray<nsCString>&& aTrackingFullHashes,
|
||||
const Maybe<mozilla::AntiTrackingCommon::StorageAccessGrantedReason>&
|
||||
const Maybe<mozilla::ContentBlockingNotifier::StorageAccessGrantedReason>&
|
||||
aReason) {
|
||||
MOZ_ASSERT(aRequestData.elapsedLoadTimeMS().isNothing());
|
||||
|
||||
|
|
|
@ -317,7 +317,7 @@ class BrowserParent final : public PBrowserParent,
|
|||
const uint32_t& aEvent, const RequestData& aRequestData,
|
||||
const bool aBlocked, const nsACString& aTrackingOrigin,
|
||||
nsTArray<nsCString>&& aTrackingFullHashes,
|
||||
const Maybe<mozilla::AntiTrackingCommon::StorageAccessGrantedReason>&
|
||||
const Maybe<mozilla::ContentBlockingNotifier::StorageAccessGrantedReason>&
|
||||
aReason);
|
||||
|
||||
mozilla::ipc::IPCResult RecvNavigationFinished();
|
||||
|
|
|
@ -95,7 +95,7 @@ using mozilla::ScrollFlags from "mozilla/PresShellForwards.h";
|
|||
using struct InputFormData from "mozilla/dom/SessionStoreMessageUtils.h";
|
||||
using struct CollectedInputDataValue from "mozilla/dom/SessionStoreMessageUtils.h";
|
||||
using refcounted class nsITransportSecurityInfo from "nsITransportSecurityInfo.h";
|
||||
using mozilla::AntiTrackingCommon::StorageAccessGrantedReason from "mozilla/AntiTrackingCommon.h";
|
||||
using mozilla::ContentBlockingNotifier::StorageAccessGrantedReason from "mozilla/ContentBlockingNotifier.h";
|
||||
using CallerType from "mozilla/dom/BindingDeclarations.h";
|
||||
|
||||
namespace mozilla {
|
||||
|
|
|
@ -311,7 +311,7 @@ void WindowGlobalParent::NotifyContentBlockingEvent(
|
|||
uint32_t aEvent, nsIRequest* aRequest, bool aBlocked,
|
||||
const nsACString& aTrackingOrigin,
|
||||
const nsTArray<nsCString>& aTrackingFullHashes,
|
||||
const Maybe<AntiTrackingCommon::StorageAccessGrantedReason>& aReason) {
|
||||
const Maybe<ContentBlockingNotifier::StorageAccessGrantedReason>& aReason) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
DebugOnly<bool> isCookiesBlockedTracker =
|
||||
aEvent == nsIWebProgressListener::STATE_COOKIES_BLOCKED_TRACKER ||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#ifndef mozilla_dom_WindowGlobalParent_h
|
||||
#define mozilla_dom_WindowGlobalParent_h
|
||||
|
||||
#include "mozilla/AntiTrackingCommon.h"
|
||||
#include "mozilla/ContentBlockingNotifier.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/dom/DOMRect.h"
|
||||
#include "mozilla/dom/PWindowGlobalParent.h"
|
||||
|
@ -146,8 +146,8 @@ class WindowGlobalParent final : public WindowContext,
|
|||
uint32_t aEvent, nsIRequest* aRequest, bool aBlocked,
|
||||
const nsACString& aTrackingOrigin,
|
||||
const nsTArray<nsCString>& aTrackingFullHashes,
|
||||
const Maybe<AntiTrackingCommon::StorageAccessGrantedReason>& aReason =
|
||||
Nothing());
|
||||
const Maybe<ContentBlockingNotifier::StorageAccessGrantedReason>&
|
||||
aReason = Nothing());
|
||||
|
||||
ContentBlockingLog* GetContentBlockingLog() { return &mContentBlockingLog; }
|
||||
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
* 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 "mozilla/AntiTrackingCommon.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/ContentBlockingNotifier.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/Likely.h"
|
||||
#include "mozilla/Printf.h"
|
||||
|
@ -2265,8 +2265,8 @@ void nsCookieService::SetCookieStringInternal(
|
|||
}
|
||||
|
||||
void nsCookieService::NotifyAccepted(nsIChannel* aChannel) {
|
||||
AntiTrackingCommon::NotifyBlockingDecision(
|
||||
aChannel, AntiTrackingCommon::BlockingDecision::eAllow, 0);
|
||||
ContentBlockingNotifier::OnDecision(
|
||||
aChannel, ContentBlockingNotifier::BlockingDecision::eAllow, 0);
|
||||
}
|
||||
|
||||
// notify observers that a cookie was rejected due to the users' prefs.
|
||||
|
@ -2282,8 +2282,9 @@ void nsCookieService::NotifyRejected(nsIURI* aHostURI, nsIChannel* aChannel,
|
|||
MOZ_ASSERT(aOperation == OPERATION_READ);
|
||||
}
|
||||
|
||||
AntiTrackingCommon::NotifyBlockingDecision(
|
||||
aChannel, AntiTrackingCommon::BlockingDecision::eBlock, aRejectedReason);
|
||||
ContentBlockingNotifier::OnDecision(
|
||||
aChannel, ContentBlockingNotifier::BlockingDecision::eBlock,
|
||||
aRejectedReason);
|
||||
}
|
||||
|
||||
// notify observers that the cookie list changed. there are five possible
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "mozilla/AntiTrackingCommon.h"
|
||||
#include "mozilla/BasePrincipal.h"
|
||||
#include "mozilla/ContentBlockingAllowList.h"
|
||||
#include "mozilla/ContentBlockingNotifier.h"
|
||||
#include "mozilla/dom/WindowGlobalParent.h"
|
||||
#include "mozilla/net/HttpBaseChannel.h"
|
||||
#include "mozilla/net/UrlClassifierFeatureFactory.h"
|
||||
|
@ -211,7 +212,7 @@ nsresult UrlClassifierCommon::SetBlockedContent(nsIChannel* channel,
|
|||
if (!state) {
|
||||
state = nsIWebProgressListener::STATE_BLOCKED_UNSAFE_CONTENT;
|
||||
}
|
||||
AntiTrackingCommon::NotifyContentBlockingEvent(channel, state);
|
||||
ContentBlockingNotifier::OnEvent(channel, state);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -443,7 +444,7 @@ void UrlClassifierCommon::AnnotateChannel(nsIChannel* aChannel,
|
|||
IsCryptominingClassificationFlag(aClassificationFlags);
|
||||
|
||||
if (validClassificationFlags && isThirdPartyWithTopLevelWinURI) {
|
||||
AntiTrackingCommon::NotifyContentBlockingEvent(aChannel, aLoadingState);
|
||||
ContentBlockingNotifier::OnEvent(aChannel, aLoadingState);
|
||||
}
|
||||
|
||||
if (isThirdPartyWithTopLevelWinURI &&
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include "AntiTrackingLog.h"
|
||||
#include "AntiTrackingCommon.h"
|
||||
#include "AntiTrackingUtils.h"
|
||||
|
||||
#include "mozilla/ContentBlockingAllowList.h"
|
||||
#include "mozilla/dom/BrowsingContext.h"
|
||||
|
@ -48,7 +49,6 @@
|
|||
#include "prtime.h"
|
||||
|
||||
#define ANTITRACKING_PERM_KEY "3rdPartyStorage"
|
||||
#define ANTITRACKING_CONSOLE_CATEGORY NS_LITERAL_CSTRING("Content Blocking")
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
@ -61,8 +61,6 @@ using mozilla::dom::BrowsingContext;
|
|||
using mozilla::dom::ContentChild;
|
||||
using mozilla::dom::Document;
|
||||
|
||||
static const uint32_t kMaxConsoleOutputDelayMs = 100;
|
||||
|
||||
namespace {
|
||||
|
||||
bool GetParentPrincipalAndTrackingOrigin(
|
||||
|
@ -180,229 +178,6 @@ int32_t CookiesBehavior(nsIPrincipal* aPrincipal,
|
|||
return aCookieJarSettings->GetCookieBehavior();
|
||||
}
|
||||
|
||||
void RunConsoleReportingRunnable(already_AddRefed<nsIRunnable>&& aRunnable) {
|
||||
if (StaticPrefs::privacy_restrict3rdpartystorage_console_lazy()) {
|
||||
nsresult rv = NS_DispatchToCurrentThreadQueue(std::move(aRunnable),
|
||||
kMaxConsoleOutputDelayMs,
|
||||
EventQueuePriority::Idle);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
nsCOMPtr<nsIRunnable> runnable(std::move(aRunnable));
|
||||
nsresult rv = runnable->Run();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ReportBlockingToConsole(uint64_t aWindowID, nsIURI* aURI,
|
||||
uint32_t aRejectedReason) {
|
||||
MOZ_ASSERT(aWindowID);
|
||||
MOZ_ASSERT(aURI);
|
||||
MOZ_ASSERT(
|
||||
aRejectedReason == 0 ||
|
||||
aRejectedReason ==
|
||||
nsIWebProgressListener::STATE_COOKIES_BLOCKED_BY_PERMISSION ||
|
||||
aRejectedReason ==
|
||||
nsIWebProgressListener::STATE_COOKIES_BLOCKED_TRACKER ||
|
||||
aRejectedReason ==
|
||||
nsIWebProgressListener::STATE_COOKIES_BLOCKED_SOCIALTRACKER ||
|
||||
aRejectedReason ==
|
||||
nsIWebProgressListener::STATE_COOKIES_PARTITIONED_FOREIGN ||
|
||||
aRejectedReason == nsIWebProgressListener::STATE_COOKIES_BLOCKED_ALL ||
|
||||
aRejectedReason == nsIWebProgressListener::STATE_COOKIES_BLOCKED_FOREIGN);
|
||||
|
||||
nsAutoString sourceLine;
|
||||
uint32_t lineNumber = 0, columnNumber = 0;
|
||||
JSContext* cx = nsContentUtils::GetCurrentJSContext();
|
||||
if (cx) {
|
||||
nsJSUtils::GetCallingLocation(cx, sourceLine, &lineNumber, &columnNumber);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> uri(aURI);
|
||||
|
||||
RefPtr<Runnable> runnable = NS_NewRunnableFunction(
|
||||
"ReportBlockingToConsoleDelayed", [aWindowID, sourceLine, lineNumber,
|
||||
columnNumber, uri, aRejectedReason]() {
|
||||
const char* message = nullptr;
|
||||
nsAutoCString category;
|
||||
// When changing this list, please make sure to update the corresponding
|
||||
// code in antitracking_head.js (inside _createTask).
|
||||
switch (aRejectedReason) {
|
||||
case nsIWebProgressListener::STATE_COOKIES_BLOCKED_BY_PERMISSION:
|
||||
message = "CookieBlockedByPermission";
|
||||
category = NS_LITERAL_CSTRING("cookieBlockedPermission");
|
||||
break;
|
||||
|
||||
case nsIWebProgressListener::STATE_COOKIES_BLOCKED_TRACKER:
|
||||
message = "CookieBlockedTracker";
|
||||
category = NS_LITERAL_CSTRING("cookieBlockedTracker");
|
||||
break;
|
||||
|
||||
case nsIWebProgressListener::STATE_COOKIES_BLOCKED_ALL:
|
||||
message = "CookieBlockedAll";
|
||||
category = NS_LITERAL_CSTRING("cookieBlockedAll");
|
||||
break;
|
||||
|
||||
case nsIWebProgressListener::STATE_COOKIES_BLOCKED_FOREIGN:
|
||||
message = "CookieBlockedForeign";
|
||||
category = NS_LITERAL_CSTRING("cookieBlockedForeign");
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(message);
|
||||
|
||||
// Strip the URL of any possible username/password and make it ready
|
||||
// to be presented in the UI.
|
||||
nsCOMPtr<nsIURIFixup> urifixup = services::GetURIFixup();
|
||||
NS_ENSURE_TRUE_VOID(urifixup);
|
||||
nsCOMPtr<nsIURI> exposableURI;
|
||||
nsresult rv =
|
||||
urifixup->CreateExposableURI(uri, getter_AddRefs(exposableURI));
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
|
||||
AutoTArray<nsString, 1> params;
|
||||
CopyUTF8toUTF16(exposableURI->GetSpecOrDefault(),
|
||||
*params.AppendElement());
|
||||
|
||||
nsAutoString errorText;
|
||||
rv = nsContentUtils::FormatLocalizedString(
|
||||
nsContentUtils::eNECKO_PROPERTIES, message, params, errorText);
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
|
||||
nsContentUtils::ReportToConsoleByWindowID(
|
||||
errorText, nsIScriptError::warningFlag, category, aWindowID,
|
||||
nullptr, sourceLine, lineNumber, columnNumber);
|
||||
});
|
||||
|
||||
RunConsoleReportingRunnable(runnable.forget());
|
||||
}
|
||||
|
||||
void ReportBlockingToConsole(nsIChannel* aChannel, nsIURI* aURI,
|
||||
uint32_t aRejectedReason) {
|
||||
MOZ_ASSERT(aChannel && aURI);
|
||||
|
||||
uint64_t windowID;
|
||||
|
||||
if (XRE_IsParentProcess()) {
|
||||
// Get the top-level window ID from the top-level BrowsingContext
|
||||
nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
|
||||
RefPtr<dom::BrowsingContext> bc;
|
||||
loadInfo->GetBrowsingContext(getter_AddRefs(bc));
|
||||
|
||||
if (!bc || bc->IsDiscarded()) {
|
||||
return;
|
||||
}
|
||||
|
||||
bc = bc->Top();
|
||||
RefPtr<dom::WindowGlobalParent> wgp =
|
||||
bc->Canonical()->GetCurrentWindowGlobal();
|
||||
if (!wgp) {
|
||||
return;
|
||||
}
|
||||
|
||||
windowID = wgp->InnerWindowId();
|
||||
} else {
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aChannel, &rv);
|
||||
|
||||
if (!httpChannel) {
|
||||
return;
|
||||
}
|
||||
|
||||
rv = httpChannel->GetTopLevelContentWindowId(&windowID);
|
||||
if (NS_FAILED(rv) || !windowID) {
|
||||
windowID = nsContentUtils::GetInnerWindowID(httpChannel);
|
||||
}
|
||||
}
|
||||
|
||||
ReportBlockingToConsole(windowID, aURI, aRejectedReason);
|
||||
}
|
||||
|
||||
void ReportUnblockingToConsole(
|
||||
nsPIDOMWindowInner* aWindow, const nsAString& aTrackingOrigin,
|
||||
AntiTrackingCommon::StorageAccessGrantedReason aReason) {
|
||||
nsCOMPtr<nsIPrincipal> principal =
|
||||
nsGlobalWindowInner::Cast(aWindow)->GetPrincipal();
|
||||
if (NS_WARN_IF(!principal)) {
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<Document> doc = aWindow->GetExtantDoc();
|
||||
if (NS_WARN_IF(!doc)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoString trackingOrigin(aTrackingOrigin);
|
||||
|
||||
nsAutoString sourceLine;
|
||||
uint32_t lineNumber = 0, columnNumber = 0;
|
||||
JSContext* cx = nsContentUtils::GetCurrentJSContext();
|
||||
if (cx) {
|
||||
nsJSUtils::GetCallingLocation(cx, sourceLine, &lineNumber, &columnNumber);
|
||||
}
|
||||
|
||||
RefPtr<Runnable> runnable = NS_NewRunnableFunction(
|
||||
"ReportUnblockingToConsoleDelayed",
|
||||
[doc, principal, trackingOrigin, sourceLine, lineNumber, columnNumber,
|
||||
aReason]() {
|
||||
nsAutoString origin;
|
||||
nsresult rv = nsContentUtils::GetUTFOrigin(principal, origin);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Not adding grantedOrigin yet because we may not want it later.
|
||||
AutoTArray<nsString, 3> params = {origin, trackingOrigin};
|
||||
const char* messageWithSameOrigin = nullptr;
|
||||
|
||||
switch (aReason) {
|
||||
case AntiTrackingCommon::eStorageAccessAPI:
|
||||
messageWithSameOrigin = "CookieAllowedForTrackerByStorageAccessAPI";
|
||||
break;
|
||||
|
||||
case AntiTrackingCommon::eOpenerAfterUserInteraction:
|
||||
[[fallthrough]];
|
||||
case AntiTrackingCommon::eOpener:
|
||||
messageWithSameOrigin = "CookieAllowedForTrackerByHeuristic";
|
||||
break;
|
||||
}
|
||||
|
||||
nsContentUtils::ReportToConsole(
|
||||
nsIScriptError::warningFlag, ANTITRACKING_CONSOLE_CATEGORY, doc,
|
||||
nsContentUtils::eNECKO_PROPERTIES, messageWithSameOrigin, params,
|
||||
nullptr, sourceLine, lineNumber, columnNumber);
|
||||
});
|
||||
|
||||
RunConsoleReportingRunnable(runnable.forget());
|
||||
}
|
||||
|
||||
already_AddRefed<nsPIDOMWindowOuter> GetTopWindow(nsPIDOMWindowInner* aWindow) {
|
||||
Document* document = aWindow->GetExtantDoc();
|
||||
if (!document) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsIChannel* channel = document->GetChannel();
|
||||
if (!channel) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowOuter> pwin =
|
||||
aWindow->GetBrowsingContext()->Top()->GetDOMWindow();
|
||||
|
||||
if (!pwin) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return pwin.forget();
|
||||
}
|
||||
|
||||
class TemporaryAccessGrantCacheKey : public PLDHashEntryHdr {
|
||||
public:
|
||||
typedef Pair<nsCOMPtr<nsIPrincipal>, nsCString> KeyType;
|
||||
|
@ -636,175 +411,17 @@ bool CheckAntiTrackingPermission(nsIPrincipal* aPrincipal,
|
|||
return true;
|
||||
}
|
||||
|
||||
// This API finishes the remaining work left in NotifyBlockingDecisionInternal.
|
||||
void NotifyAllowDecisionInternal(nsIChannel* aReportingChannel,
|
||||
nsIChannel* aTrackingChannel, nsIURI* aURI,
|
||||
nsPIDOMWindowOuter* aWindow) {
|
||||
nsAutoCString trackingOrigin;
|
||||
if (aURI) {
|
||||
Unused << nsContentUtils::GetASCIIOrigin(aURI, trackingOrigin);
|
||||
}
|
||||
|
||||
// This can be called in either the parent process or the child processes.
|
||||
|
||||
// Now send the generic "cookies loaded" notifications, from the most generic
|
||||
// to the most specific.
|
||||
AntiTrackingCommon::NotifyContentBlockingEvent(
|
||||
aWindow, aReportingChannel, aTrackingChannel, false,
|
||||
nsIWebProgressListener::STATE_COOKIES_LOADED, trackingOrigin);
|
||||
|
||||
nsCOMPtr<nsIClassifiedChannel> classifiedChannel =
|
||||
do_QueryInterface(aTrackingChannel);
|
||||
if (!classifiedChannel) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t classificationFlags =
|
||||
classifiedChannel->GetThirdPartyClassificationFlags();
|
||||
if (classificationFlags &
|
||||
nsIClassifiedChannel::ClassificationFlags::CLASSIFIED_TRACKING) {
|
||||
AntiTrackingCommon::NotifyContentBlockingEvent(
|
||||
aWindow, aReportingChannel, aTrackingChannel, false,
|
||||
nsIWebProgressListener::STATE_COOKIES_LOADED_TRACKER, trackingOrigin);
|
||||
}
|
||||
|
||||
if (classificationFlags &
|
||||
nsIClassifiedChannel::ClassificationFlags::CLASSIFIED_SOCIALTRACKING) {
|
||||
AntiTrackingCommon::NotifyContentBlockingEvent(
|
||||
aWindow, aReportingChannel, aTrackingChannel, false,
|
||||
nsIWebProgressListener::STATE_COOKIES_LOADED_SOCIALTRACKER,
|
||||
trackingOrigin);
|
||||
}
|
||||
}
|
||||
|
||||
void NotifyBlockingDecisionInternal(
|
||||
nsIChannel* aReportingChannel, nsIChannel* aTrackingChannel,
|
||||
AntiTrackingCommon::BlockingDecision aDecision, uint32_t aRejectedReason,
|
||||
nsIURI* aURI, nsPIDOMWindowOuter* aWindow) {
|
||||
MOZ_ASSERT(aWindow);
|
||||
|
||||
// When this is called with system priviledged, the decision should always be
|
||||
// ALLOW, and we can also stop processing this event.
|
||||
if (nsGlobalWindowOuter::Cast(aWindow)->GetPrincipal() ==
|
||||
nsContentUtils::GetSystemPrincipal()) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(aDecision ==
|
||||
AntiTrackingCommon::BlockingDecision::eAllow);
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoCString trackingOrigin;
|
||||
if (aURI) {
|
||||
Unused << nsContentUtils::GetASCIIOrigin(aURI, trackingOrigin);
|
||||
}
|
||||
|
||||
if (aDecision == AntiTrackingCommon::BlockingDecision::eBlock) {
|
||||
AntiTrackingCommon::NotifyContentBlockingEvent(
|
||||
aWindow, aReportingChannel, aTrackingChannel, true, aRejectedReason,
|
||||
trackingOrigin);
|
||||
|
||||
ReportBlockingToConsole(aReportingChannel, aURI, aRejectedReason);
|
||||
}
|
||||
|
||||
NotifyAllowDecisionInternal(aReportingChannel, aTrackingChannel, aURI,
|
||||
aWindow);
|
||||
}
|
||||
|
||||
void NotifyBlockingDecisionInternal(
|
||||
nsIChannel* aReportingChannel, nsIChannel* aTrackingChannel,
|
||||
AntiTrackingCommon::BlockingDecision aDecision, uint32_t aRejectedReason,
|
||||
nsIURI* aURI) {
|
||||
// Can be called only in the parent process when there is no window.
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
|
||||
nsAutoCString trackingOrigin;
|
||||
if (aURI) {
|
||||
Unused << nsContentUtils::GetASCIIOrigin(aURI, trackingOrigin);
|
||||
}
|
||||
|
||||
if (aDecision == AntiTrackingCommon::BlockingDecision::eBlock) {
|
||||
AntiTrackingCommon::NotifyContentBlockingEvent(
|
||||
nullptr, aReportingChannel, aTrackingChannel, true, aRejectedReason,
|
||||
trackingOrigin);
|
||||
|
||||
ReportBlockingToConsole(aReportingChannel, aURI, aRejectedReason);
|
||||
}
|
||||
|
||||
NotifyAllowDecisionInternal(aReportingChannel, aTrackingChannel, aURI,
|
||||
nullptr);
|
||||
}
|
||||
|
||||
// Send a message to notify OnContentBlockingEvent in the parent, which will
|
||||
// update the ContentBlockingLog in the parent.
|
||||
void NotifyContentBlockingEventInChild(
|
||||
nsPIDOMWindowOuter* aWindow, nsIChannel* aReportingChannel,
|
||||
nsIChannel* aTrackingChannel, bool aBlocked, uint32_t aRejectedReason,
|
||||
const nsACString& aTrackingOrigin,
|
||||
const Maybe<AntiTrackingCommon::StorageAccessGrantedReason>& aReason) {
|
||||
MOZ_ASSERT(XRE_IsContentProcess());
|
||||
MOZ_ASSERT(aWindow);
|
||||
|
||||
RefPtr<dom::BrowserChild> browserChild = dom::BrowserChild::GetFrom(aWindow);
|
||||
NS_ENSURE_TRUE_VOID(browserChild);
|
||||
|
||||
nsTArray<nsCString> trackingFullHashes;
|
||||
nsCOMPtr<nsIClassifiedChannel> classifiedChannel =
|
||||
do_QueryInterface(aTrackingChannel);
|
||||
|
||||
if (classifiedChannel) {
|
||||
Unused << classifiedChannel->GetMatchedTrackingFullHashes(
|
||||
trackingFullHashes);
|
||||
}
|
||||
|
||||
browserChild->NotifyContentBlockingEvent(aRejectedReason, aReportingChannel,
|
||||
aBlocked, aTrackingOrigin,
|
||||
trackingFullHashes, aReason);
|
||||
}
|
||||
|
||||
// Update the ContentBlockingLog of the top-level WindowGlobalParent of
|
||||
// the reporting channel.
|
||||
void NotifyContentBlockingEventInParent(
|
||||
nsIChannel* aReportingChannel, nsIChannel* aTrackingChannel, bool aBlocked,
|
||||
uint32_t aRejectedReason, const nsACString& aTrackingOrigin,
|
||||
const Maybe<AntiTrackingCommon::StorageAccessGrantedReason>& aReason) {
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
|
||||
nsCOMPtr<nsILoadInfo> loadInfo = aReportingChannel->LoadInfo();
|
||||
RefPtr<dom::BrowsingContext> bc;
|
||||
loadInfo->GetBrowsingContext(getter_AddRefs(bc));
|
||||
|
||||
if (!bc || bc->IsDiscarded()) {
|
||||
return;
|
||||
}
|
||||
|
||||
bc = bc->Top();
|
||||
RefPtr<dom::WindowGlobalParent> wgp =
|
||||
bc->Canonical()->GetCurrentWindowGlobal();
|
||||
NS_ENSURE_TRUE_VOID(wgp);
|
||||
|
||||
nsTArray<nsCString> trackingFullHashes;
|
||||
nsCOMPtr<nsIClassifiedChannel> classifiedChannel =
|
||||
do_QueryInterface(aTrackingChannel);
|
||||
|
||||
if (classifiedChannel) {
|
||||
Unused << classifiedChannel->GetMatchedTrackingFullHashes(
|
||||
trackingFullHashes);
|
||||
}
|
||||
|
||||
wgp->NotifyContentBlockingEvent(aRejectedReason, aReportingChannel, aBlocked,
|
||||
aTrackingOrigin, trackingFullHashes, aReason);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
/* static */ RefPtr<AntiTrackingCommon::StorageAccessGrantPromise>
|
||||
AntiTrackingCommon::AddFirstPartyStorageAccessGrantedFor(
|
||||
nsIPrincipal* aPrincipal, nsPIDOMWindowInner* aParentWindow,
|
||||
StorageAccessGrantedReason aReason,
|
||||
ContentBlockingNotifier::StorageAccessGrantedReason aReason,
|
||||
const AntiTrackingCommon::PerformFinalChecks& aPerformFinalChecks) {
|
||||
MOZ_ASSERT(aParentWindow);
|
||||
|
||||
switch (aReason) {
|
||||
case eOpener:
|
||||
case ContentBlockingNotifier::eOpener:
|
||||
if (!StaticPrefs::
|
||||
privacy_restrict3rdpartystorage_heuristic_window_open()) {
|
||||
LOG(
|
||||
|
@ -814,7 +431,7 @@ AntiTrackingCommon::AddFirstPartyStorageAccessGrantedFor(
|
|||
return StorageAccessGrantPromise::CreateAndReject(false, __func__);
|
||||
}
|
||||
break;
|
||||
case eOpenerAfterUserInteraction:
|
||||
case ContentBlockingNotifier::eOpenerAfterUserInteraction:
|
||||
if (!StaticPrefs::
|
||||
privacy_restrict3rdpartystorage_heuristic_opened_window_after_interaction()) {
|
||||
LOG(
|
||||
|
@ -976,12 +593,14 @@ AntiTrackingCommon::AddFirstPartyStorageAccessGrantedFor(
|
|||
"refusing to add a first-party storage permission to access it",
|
||||
_spec),
|
||||
trackingPrincipal);
|
||||
NotifyBlockingDecision(aParentWindow, BlockingDecision::eBlock,
|
||||
blockReason);
|
||||
ContentBlockingNotifier::OnDecision(
|
||||
aParentWindow, ContentBlockingNotifier::BlockingDecision::eBlock,
|
||||
blockReason);
|
||||
return StorageAccessGrantPromise::CreateAndReject(false, __func__);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowOuter> pwin = GetTopWindow(parentWindow);
|
||||
nsCOMPtr<nsPIDOMWindowOuter> pwin =
|
||||
AntiTrackingUtils::GetTopWindow(parentWindow);
|
||||
if (!pwin) {
|
||||
LOG(("Couldn't get the top window"));
|
||||
return StorageAccessGrantPromise::CreateAndReject(false, __func__);
|
||||
|
@ -1003,12 +622,12 @@ AntiTrackingCommon::AddFirstPartyStorageAccessGrantedFor(
|
|||
nsIChannel* channel =
|
||||
pwin->GetCurrentInnerWindow()->GetExtantDoc()->GetChannel();
|
||||
|
||||
NotifyContentBlockingEvent(
|
||||
ContentBlockingNotifier::OnEvent(
|
||||
pwin, channel, parentWindow->GetExtantDoc()->GetChannel(), false,
|
||||
blockReason, trackingOrigin, Some(aReason));
|
||||
|
||||
ReportUnblockingToConsole(parentWindow,
|
||||
NS_ConvertUTF8toUTF16(trackingOrigin), aReason);
|
||||
ContentBlockingNotifier::ReportUnblockingToConsole(
|
||||
parentWindow, NS_ConvertUTF8toUTF16(trackingOrigin), aReason);
|
||||
|
||||
if (XRE_IsParentProcess()) {
|
||||
LOG(("Saving the permission: trackingOrigin=%s", trackingOrigin.get()));
|
||||
|
@ -1740,111 +1359,6 @@ bool AntiTrackingCommon::MaybeIsFirstPartyStorageAccessGrantedFor(
|
|||
nsContentUtils::IsInPrivateBrowsing(parentDocument), nullptr, 0);
|
||||
}
|
||||
|
||||
/* static */
|
||||
void AntiTrackingCommon::NotifyBlockingDecision(nsIChannel* aChannel,
|
||||
BlockingDecision aDecision,
|
||||
uint32_t aRejectedReason) {
|
||||
MOZ_ASSERT(
|
||||
aRejectedReason == 0 ||
|
||||
aRejectedReason ==
|
||||
nsIWebProgressListener::STATE_COOKIES_BLOCKED_BY_PERMISSION ||
|
||||
aRejectedReason ==
|
||||
nsIWebProgressListener::STATE_COOKIES_BLOCKED_TRACKER ||
|
||||
aRejectedReason ==
|
||||
nsIWebProgressListener::STATE_COOKIES_BLOCKED_SOCIALTRACKER ||
|
||||
aRejectedReason ==
|
||||
nsIWebProgressListener::STATE_COOKIES_PARTITIONED_FOREIGN ||
|
||||
aRejectedReason == nsIWebProgressListener::STATE_COOKIES_BLOCKED_ALL ||
|
||||
aRejectedReason == nsIWebProgressListener::STATE_COOKIES_BLOCKED_FOREIGN);
|
||||
MOZ_ASSERT(aDecision == BlockingDecision::eBlock ||
|
||||
aDecision == BlockingDecision::eAllow);
|
||||
|
||||
if (!aChannel) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
aChannel->GetURI(getter_AddRefs(uri));
|
||||
|
||||
// Can be called in EITHER the parent or child process.
|
||||
// Window is only needed while in child processes.
|
||||
if (XRE_IsParentProcess()) {
|
||||
NotifyBlockingDecisionInternal(aChannel, aChannel, aDecision,
|
||||
aRejectedReason, uri);
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(XRE_IsContentProcess());
|
||||
|
||||
nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil = services::GetThirdPartyUtil();
|
||||
if (!thirdPartyUtil) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> uriBeingLoaded = MaybeGetDocumentURIBeingLoaded(aChannel);
|
||||
nsCOMPtr<mozIDOMWindowProxy> win;
|
||||
nsresult rv = thirdPartyUtil->GetTopWindowForChannel(aChannel, uriBeingLoaded,
|
||||
getter_AddRefs(win));
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowOuter> pwin = nsPIDOMWindowOuter::From(win);
|
||||
if (!pwin) {
|
||||
return;
|
||||
}
|
||||
|
||||
NotifyBlockingDecisionInternal(aChannel, aChannel, aDecision, aRejectedReason,
|
||||
uri, pwin);
|
||||
}
|
||||
|
||||
/* static */
|
||||
void AntiTrackingCommon::NotifyBlockingDecision(nsPIDOMWindowInner* aWindow,
|
||||
BlockingDecision aDecision,
|
||||
uint32_t aRejectedReason) {
|
||||
MOZ_ASSERT(aWindow);
|
||||
MOZ_ASSERT(
|
||||
aRejectedReason == 0 ||
|
||||
aRejectedReason ==
|
||||
nsIWebProgressListener::STATE_COOKIES_BLOCKED_BY_PERMISSION ||
|
||||
aRejectedReason ==
|
||||
nsIWebProgressListener::STATE_COOKIES_BLOCKED_TRACKER ||
|
||||
aRejectedReason ==
|
||||
nsIWebProgressListener::STATE_COOKIES_BLOCKED_SOCIALTRACKER ||
|
||||
aRejectedReason ==
|
||||
nsIWebProgressListener::STATE_COOKIES_PARTITIONED_FOREIGN ||
|
||||
aRejectedReason == nsIWebProgressListener::STATE_COOKIES_BLOCKED_ALL ||
|
||||
aRejectedReason == nsIWebProgressListener::STATE_COOKIES_BLOCKED_FOREIGN);
|
||||
MOZ_ASSERT(aDecision == BlockingDecision::eBlock ||
|
||||
aDecision == BlockingDecision::eAllow);
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowOuter> pwin = GetTopWindow(aWindow);
|
||||
if (!pwin) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsPIDOMWindowInner* inner = pwin->GetCurrentInnerWindow();
|
||||
if (!inner) {
|
||||
return;
|
||||
}
|
||||
Document* pwinDoc = inner->GetExtantDoc();
|
||||
if (!pwinDoc) {
|
||||
return;
|
||||
}
|
||||
nsIChannel* channel = pwinDoc->GetChannel();
|
||||
if (!channel) {
|
||||
return;
|
||||
}
|
||||
|
||||
Document* document = aWindow->GetExtantDoc();
|
||||
if (!document) {
|
||||
return;
|
||||
}
|
||||
nsIURI* uri = document->GetDocumentURI();
|
||||
nsIChannel* trackingChannel = document->GetChannel();
|
||||
|
||||
NotifyBlockingDecisionInternal(channel, trackingChannel, aDecision,
|
||||
aRejectedReason, uri, pwin);
|
||||
}
|
||||
|
||||
/* static */
|
||||
void AntiTrackingCommon::StoreUserInteractionFor(nsIPrincipal* aPrincipal) {
|
||||
if (!aPrincipal) {
|
||||
|
@ -1931,40 +1445,6 @@ already_AddRefed<nsIURI> AntiTrackingCommon::MaybeGetDocumentURIBeingLoaded(
|
|||
return uriBeingLoaded.forget();
|
||||
}
|
||||
|
||||
/* static */
|
||||
void AntiTrackingCommon::NotifyContentBlockingEvent(nsIChannel* aChannel,
|
||||
uint32_t aRejectedReason) {
|
||||
MOZ_ASSERT(XRE_IsParentProcess() && aChannel);
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
aChannel->GetURI(getter_AddRefs(uri));
|
||||
|
||||
nsAutoCString trackingOrigin;
|
||||
if (uri) {
|
||||
Unused << nsContentUtils::GetASCIIOrigin(uri, trackingOrigin);
|
||||
}
|
||||
|
||||
return AntiTrackingCommon::NotifyContentBlockingEvent(
|
||||
nullptr, aChannel, aChannel, true, aRejectedReason, trackingOrigin);
|
||||
}
|
||||
|
||||
/* static */
|
||||
void AntiTrackingCommon::NotifyContentBlockingEvent(
|
||||
nsPIDOMWindowOuter* aWindow, nsIChannel* aReportingChannel,
|
||||
nsIChannel* aTrackingChannel, bool aBlocked, uint32_t aRejectedReason,
|
||||
const nsACString& aTrackingOrigin,
|
||||
const Maybe<StorageAccessGrantedReason>& aReason) {
|
||||
if (XRE_IsParentProcess()) {
|
||||
NotifyContentBlockingEventInParent(aReportingChannel, aTrackingChannel,
|
||||
aBlocked, aRejectedReason,
|
||||
aTrackingOrigin, aReason);
|
||||
} else {
|
||||
NotifyContentBlockingEventInChild(
|
||||
aWindow, aReportingChannel, aTrackingChannel, aBlocked, aRejectedReason,
|
||||
aTrackingOrigin, aReason);
|
||||
}
|
||||
}
|
||||
|
||||
/* static */
|
||||
void AntiTrackingCommon::RedirectHeuristic(nsIChannel* aOldChannel,
|
||||
nsIURI* aOldURI,
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#define mozilla_antitrackingservice_h
|
||||
|
||||
#include "nsString.h"
|
||||
#include "mozilla/ContentBlockingNotifier.h"
|
||||
#include "mozilla/MozPromise.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/StaticPrefs_privacy.h"
|
||||
|
@ -73,11 +74,6 @@ class AntiTrackingCommon final {
|
|||
static bool IsFirstPartyStorageAccessGrantedFor(
|
||||
nsIPrincipal* aPrincipal, nsICookieJarSettings* aCookieJarSettings);
|
||||
|
||||
enum StorageAccessGrantedReason {
|
||||
eStorageAccessAPI,
|
||||
eOpenerAfterUserInteraction,
|
||||
eOpener
|
||||
};
|
||||
enum StorageAccessPromptChoices { eAllow, eAllowAutoGrant };
|
||||
|
||||
// Grant the permission for aOrigin to have access to the first party storage.
|
||||
|
@ -102,7 +98,7 @@ class AntiTrackingCommon final {
|
|||
static MOZ_MUST_USE RefPtr<StorageAccessGrantPromise>
|
||||
AddFirstPartyStorageAccessGrantedFor(
|
||||
nsIPrincipal* aPrincipal, nsPIDOMWindowInner* aParentWindow,
|
||||
StorageAccessGrantedReason aReason,
|
||||
ContentBlockingNotifier::StorageAccessGrantedReason aReason,
|
||||
const PerformFinalChecks& aPerformFinalChecks = nullptr);
|
||||
|
||||
// Given a principal, returns the storage permission key that will be used for
|
||||
|
@ -128,45 +124,10 @@ class AntiTrackingCommon final {
|
|||
uint64_t aExpirationTime =
|
||||
StaticPrefs::privacy_restrict3rdpartystorage_expiration());
|
||||
|
||||
enum class BlockingDecision {
|
||||
eBlock,
|
||||
eAllow,
|
||||
};
|
||||
|
||||
// This method can be called on the parent process or on the content process.
|
||||
// The notification is propagated to the child channel if aChannel is a parent
|
||||
// channel proxy.
|
||||
//
|
||||
// aDecision can be eBlock if we have decided to block some content, or eAllow
|
||||
// if we have decided to allow the content through.
|
||||
//
|
||||
// aRejectedReason must be one of these values:
|
||||
// * nsIWebProgressListener::STATE_COOKIES_BLOCKED_BY_PERMISSION
|
||||
// * nsIWebProgressListener::STATE_COOKIES_BLOCKED_TRACKER
|
||||
// * nsIWebProgressListener::STATE_COOKIES_BLOCKED_SOCIALTRACKER
|
||||
// * nsIWebProgressListener::STATE_COOKIES_BLOCKED_ALL
|
||||
// * nsIWebProgressListener::STATE_COOKIES_BLOCKED_FOREIGN
|
||||
static void NotifyBlockingDecision(nsIChannel* aChannel,
|
||||
BlockingDecision aDecision,
|
||||
uint32_t aRejectedReason);
|
||||
|
||||
static void NotifyBlockingDecision(nsPIDOMWindowInner* aWindow,
|
||||
BlockingDecision aDecision,
|
||||
uint32_t aRejectedReason);
|
||||
|
||||
// Get the current document URI from a document channel as it is being loaded.
|
||||
static already_AddRefed<nsIURI> MaybeGetDocumentURIBeingLoaded(
|
||||
nsIChannel* aChannel);
|
||||
|
||||
static void NotifyContentBlockingEvent(nsIChannel* aChannel,
|
||||
uint32_t aRejectedReason);
|
||||
|
||||
static void NotifyContentBlockingEvent(
|
||||
nsPIDOMWindowOuter* aWindow, nsIChannel* aReportingChannel,
|
||||
nsIChannel* aTrackingChannel, bool aBlocked, uint32_t aRejectedReason,
|
||||
const nsACString& aTrackingOrigin,
|
||||
const Maybe<StorageAccessGrantedReason>& aReason = Nothing());
|
||||
|
||||
static void RedirectHeuristic(nsIChannel* aOldChannel, nsIURI* aOldURI,
|
||||
nsIChannel* aNewChannel, nsIURI* aNewURI);
|
||||
};
|
||||
|
|
|
@ -9,19 +9,20 @@
|
|||
|
||||
#include "ipc/IPCMessageUtils.h"
|
||||
|
||||
#include "mozilla/AntiTrackingCommon.h"
|
||||
#include "mozilla/ContentBlockingNotifier.h"
|
||||
|
||||
namespace IPC {
|
||||
|
||||
// For allowing passing the enum AntiTrackingCommon::StorageAccessGrantedReason
|
||||
// over IPC.
|
||||
// For allowing passing the enum
|
||||
// ContentBlockingNotifier::StorageAccessGrantedReason over IPC.
|
||||
template <>
|
||||
struct ParamTraits<mozilla::AntiTrackingCommon::StorageAccessGrantedReason>
|
||||
struct ParamTraits<mozilla::ContentBlockingNotifier::StorageAccessGrantedReason>
|
||||
: public ContiguousEnumSerializerInclusive<
|
||||
mozilla::AntiTrackingCommon::StorageAccessGrantedReason,
|
||||
mozilla::AntiTrackingCommon::StorageAccessGrantedReason::
|
||||
mozilla::ContentBlockingNotifier::StorageAccessGrantedReason,
|
||||
mozilla::ContentBlockingNotifier::StorageAccessGrantedReason::
|
||||
eStorageAccessAPI,
|
||||
mozilla::AntiTrackingCommon::StorageAccessGrantedReason::eOpener> {};
|
||||
mozilla::ContentBlockingNotifier::StorageAccessGrantedReason::
|
||||
eOpener> {};
|
||||
|
||||
} // namespace IPC
|
||||
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/* -*- 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 "AntiTrackingUtils.h"
|
||||
|
||||
#include "mozilla/dom/BrowsingContext.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
/* static */ already_AddRefed<nsPIDOMWindowOuter>
|
||||
AntiTrackingUtils::GetTopWindow(nsPIDOMWindowInner* aWindow) {
|
||||
Document* document = aWindow->GetExtantDoc();
|
||||
if (!document) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsIChannel* channel = document->GetChannel();
|
||||
if (!channel) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowOuter> pwin =
|
||||
aWindow->GetBrowsingContext()->Top()->GetDOMWindow();
|
||||
|
||||
if (!pwin) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return pwin.forget();
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
/* -*- 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_antitrackingutils_h
|
||||
#define mozilla_antitrackingutils_h
|
||||
|
||||
#include "mozilla/AlreadyAddRefed.h"
|
||||
|
||||
class nsPIDOMWindowInner;
|
||||
class nsPIDOMWindowOuter;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class AntiTrackingUtils final {
|
||||
public:
|
||||
static already_AddRefed<nsPIDOMWindowOuter> GetTopWindow(
|
||||
nsPIDOMWindowInner* aWindow);
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_antitrackingutils_h
|
|
@ -0,0 +1,531 @@
|
|||
/* -*- 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 "AntiTrackingLog.h"
|
||||
#include "ContentBlockingNotifier.h"
|
||||
#include "AntiTrackingCommon.h"
|
||||
#include "AntiTrackingUtils.h"
|
||||
|
||||
#include "mozilla/AbstractEventQueue.h"
|
||||
#include "mozilla/StaticPrefs_privacy.h"
|
||||
#include "mozilla/dom/BrowserChild.h"
|
||||
#include "mozilla/dom/BrowsingContext.h"
|
||||
#include "mozilla/dom/WindowGlobalParent.h"
|
||||
#include "nsIClassifiedChannel.h"
|
||||
#include "nsIRunnable.h"
|
||||
#include "nsIScriptError.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsIURIFixup.h"
|
||||
#include "nsGlobalWindowInner.h"
|
||||
#include "nsJSUtils.h"
|
||||
#include "mozIThirdPartyUtil.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using mozilla::dom::BrowsingContext;
|
||||
using mozilla::dom::ContentChild;
|
||||
using mozilla::dom::Document;
|
||||
|
||||
static const uint32_t kMaxConsoleOutputDelayMs = 100;
|
||||
|
||||
namespace {
|
||||
|
||||
void RunConsoleReportingRunnable(already_AddRefed<nsIRunnable>&& aRunnable) {
|
||||
if (StaticPrefs::privacy_restrict3rdpartystorage_console_lazy()) {
|
||||
nsresult rv = NS_DispatchToCurrentThreadQueue(std::move(aRunnable),
|
||||
kMaxConsoleOutputDelayMs,
|
||||
EventQueuePriority::Idle);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
nsCOMPtr<nsIRunnable> runnable(std::move(aRunnable));
|
||||
nsresult rv = runnable->Run();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ReportBlockingToConsole(uint64_t aWindowID, nsIURI* aURI,
|
||||
uint32_t aRejectedReason) {
|
||||
MOZ_ASSERT(aWindowID);
|
||||
MOZ_ASSERT(aURI);
|
||||
MOZ_ASSERT(
|
||||
aRejectedReason == 0 ||
|
||||
aRejectedReason ==
|
||||
nsIWebProgressListener::STATE_COOKIES_BLOCKED_BY_PERMISSION ||
|
||||
aRejectedReason ==
|
||||
nsIWebProgressListener::STATE_COOKIES_BLOCKED_TRACKER ||
|
||||
aRejectedReason ==
|
||||
nsIWebProgressListener::STATE_COOKIES_BLOCKED_SOCIALTRACKER ||
|
||||
aRejectedReason ==
|
||||
nsIWebProgressListener::STATE_COOKIES_PARTITIONED_FOREIGN ||
|
||||
aRejectedReason == nsIWebProgressListener::STATE_COOKIES_BLOCKED_ALL ||
|
||||
aRejectedReason == nsIWebProgressListener::STATE_COOKIES_BLOCKED_FOREIGN);
|
||||
|
||||
nsAutoString sourceLine;
|
||||
uint32_t lineNumber = 0, columnNumber = 0;
|
||||
JSContext* cx = nsContentUtils::GetCurrentJSContext();
|
||||
if (cx) {
|
||||
nsJSUtils::GetCallingLocation(cx, sourceLine, &lineNumber, &columnNumber);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> uri(aURI);
|
||||
|
||||
RefPtr<Runnable> runnable = NS_NewRunnableFunction(
|
||||
"ReportBlockingToConsoleDelayed", [aWindowID, sourceLine, lineNumber,
|
||||
columnNumber, uri, aRejectedReason]() {
|
||||
const char* message = nullptr;
|
||||
nsAutoCString category;
|
||||
// When changing this list, please make sure to update the corresponding
|
||||
// code in antitracking_head.js (inside _createTask).
|
||||
switch (aRejectedReason) {
|
||||
case nsIWebProgressListener::STATE_COOKIES_BLOCKED_BY_PERMISSION:
|
||||
message = "CookieBlockedByPermission";
|
||||
category = NS_LITERAL_CSTRING("cookieBlockedPermission");
|
||||
break;
|
||||
|
||||
case nsIWebProgressListener::STATE_COOKIES_BLOCKED_TRACKER:
|
||||
message = "CookieBlockedTracker";
|
||||
category = NS_LITERAL_CSTRING("cookieBlockedTracker");
|
||||
break;
|
||||
|
||||
case nsIWebProgressListener::STATE_COOKIES_BLOCKED_ALL:
|
||||
message = "CookieBlockedAll";
|
||||
category = NS_LITERAL_CSTRING("cookieBlockedAll");
|
||||
break;
|
||||
|
||||
case nsIWebProgressListener::STATE_COOKIES_BLOCKED_FOREIGN:
|
||||
message = "CookieBlockedForeign";
|
||||
category = NS_LITERAL_CSTRING("cookieBlockedForeign");
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(message);
|
||||
|
||||
// Strip the URL of any possible username/password and make it ready
|
||||
// to be presented in the UI.
|
||||
nsCOMPtr<nsIURIFixup> urifixup = services::GetURIFixup();
|
||||
NS_ENSURE_TRUE_VOID(urifixup);
|
||||
nsCOMPtr<nsIURI> exposableURI;
|
||||
nsresult rv =
|
||||
urifixup->CreateExposableURI(uri, getter_AddRefs(exposableURI));
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
|
||||
AutoTArray<nsString, 1> params;
|
||||
CopyUTF8toUTF16(exposableURI->GetSpecOrDefault(),
|
||||
*params.AppendElement());
|
||||
|
||||
nsAutoString errorText;
|
||||
rv = nsContentUtils::FormatLocalizedString(
|
||||
nsContentUtils::eNECKO_PROPERTIES, message, params, errorText);
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
|
||||
nsContentUtils::ReportToConsoleByWindowID(
|
||||
errorText, nsIScriptError::warningFlag, category, aWindowID,
|
||||
nullptr, sourceLine, lineNumber, columnNumber);
|
||||
});
|
||||
|
||||
RunConsoleReportingRunnable(runnable.forget());
|
||||
}
|
||||
|
||||
void ReportBlockingToConsole(nsIChannel* aChannel, nsIURI* aURI,
|
||||
uint32_t aRejectedReason) {
|
||||
MOZ_ASSERT(aChannel && aURI);
|
||||
|
||||
uint64_t windowID;
|
||||
|
||||
if (XRE_IsParentProcess()) {
|
||||
// Get the top-level window ID from the top-level BrowsingContext
|
||||
nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
|
||||
RefPtr<dom::BrowsingContext> bc;
|
||||
loadInfo->GetBrowsingContext(getter_AddRefs(bc));
|
||||
|
||||
if (!bc || bc->IsDiscarded()) {
|
||||
return;
|
||||
}
|
||||
|
||||
bc = bc->Top();
|
||||
RefPtr<dom::WindowGlobalParent> wgp =
|
||||
bc->Canonical()->GetCurrentWindowGlobal();
|
||||
if (!wgp) {
|
||||
return;
|
||||
}
|
||||
|
||||
windowID = wgp->InnerWindowId();
|
||||
} else {
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aChannel, &rv);
|
||||
|
||||
if (!httpChannel) {
|
||||
return;
|
||||
}
|
||||
|
||||
rv = httpChannel->GetTopLevelContentWindowId(&windowID);
|
||||
if (NS_FAILED(rv) || !windowID) {
|
||||
windowID = nsContentUtils::GetInnerWindowID(httpChannel);
|
||||
}
|
||||
}
|
||||
|
||||
ReportBlockingToConsole(windowID, aURI, aRejectedReason);
|
||||
}
|
||||
|
||||
// This API finishes the remaining work left in NotifyBlockingDecision.
|
||||
void NotifyAllowDecision(nsIChannel* aReportingChannel,
|
||||
nsIChannel* aTrackingChannel, nsIURI* aURI,
|
||||
nsPIDOMWindowOuter* aWindow) {
|
||||
nsAutoCString trackingOrigin;
|
||||
if (aURI) {
|
||||
Unused << nsContentUtils::GetASCIIOrigin(aURI, trackingOrigin);
|
||||
}
|
||||
|
||||
// This can be called in either the parent process or the child processes.
|
||||
|
||||
// Now send the generic "cookies loaded" notifications, from the most generic
|
||||
// to the most specific.
|
||||
ContentBlockingNotifier::OnEvent(
|
||||
aWindow, aReportingChannel, aTrackingChannel, false,
|
||||
nsIWebProgressListener::STATE_COOKIES_LOADED, trackingOrigin);
|
||||
|
||||
nsCOMPtr<nsIClassifiedChannel> classifiedChannel =
|
||||
do_QueryInterface(aTrackingChannel);
|
||||
if (!classifiedChannel) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t classificationFlags =
|
||||
classifiedChannel->GetThirdPartyClassificationFlags();
|
||||
if (classificationFlags &
|
||||
nsIClassifiedChannel::ClassificationFlags::CLASSIFIED_TRACKING) {
|
||||
ContentBlockingNotifier::OnEvent(
|
||||
aWindow, aReportingChannel, aTrackingChannel, false,
|
||||
nsIWebProgressListener::STATE_COOKIES_LOADED_TRACKER, trackingOrigin);
|
||||
}
|
||||
|
||||
if (classificationFlags &
|
||||
nsIClassifiedChannel::ClassificationFlags::CLASSIFIED_SOCIALTRACKING) {
|
||||
ContentBlockingNotifier::OnEvent(
|
||||
aWindow, aReportingChannel, aTrackingChannel, false,
|
||||
nsIWebProgressListener::STATE_COOKIES_LOADED_SOCIALTRACKER,
|
||||
trackingOrigin);
|
||||
}
|
||||
}
|
||||
|
||||
void NotifyBlockingDecision(nsIChannel* aReportingChannel,
|
||||
nsIChannel* aTrackingChannel,
|
||||
ContentBlockingNotifier::BlockingDecision aDecision,
|
||||
uint32_t aRejectedReason, nsIURI* aURI,
|
||||
nsPIDOMWindowOuter* aWindow) {
|
||||
MOZ_ASSERT(aWindow);
|
||||
|
||||
// When this is called with system priviledged, the decision should always be
|
||||
// ALLOW, and we can also stop processing this event.
|
||||
if (nsGlobalWindowOuter::Cast(aWindow)->GetPrincipal() ==
|
||||
nsContentUtils::GetSystemPrincipal()) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(aDecision ==
|
||||
ContentBlockingNotifier::BlockingDecision::eAllow);
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoCString trackingOrigin;
|
||||
if (aURI) {
|
||||
Unused << nsContentUtils::GetASCIIOrigin(aURI, trackingOrigin);
|
||||
}
|
||||
|
||||
if (aDecision == ContentBlockingNotifier::BlockingDecision::eBlock) {
|
||||
ContentBlockingNotifier::OnEvent(aWindow, aReportingChannel,
|
||||
aTrackingChannel, true, aRejectedReason,
|
||||
trackingOrigin);
|
||||
|
||||
ReportBlockingToConsole(aReportingChannel, aURI, aRejectedReason);
|
||||
}
|
||||
|
||||
NotifyAllowDecision(aReportingChannel, aTrackingChannel, aURI, aWindow);
|
||||
}
|
||||
|
||||
void NotifyBlockingDecision(nsIChannel* aReportingChannel,
|
||||
nsIChannel* aTrackingChannel,
|
||||
ContentBlockingNotifier::BlockingDecision aDecision,
|
||||
uint32_t aRejectedReason, nsIURI* aURI) {
|
||||
// Can be called only in the parent process when there is no window.
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
|
||||
nsAutoCString trackingOrigin;
|
||||
if (aURI) {
|
||||
Unused << nsContentUtils::GetASCIIOrigin(aURI, trackingOrigin);
|
||||
}
|
||||
|
||||
if (aDecision == ContentBlockingNotifier::BlockingDecision::eBlock) {
|
||||
ContentBlockingNotifier::OnEvent(nullptr, aReportingChannel,
|
||||
aTrackingChannel, true, aRejectedReason,
|
||||
trackingOrigin);
|
||||
|
||||
ReportBlockingToConsole(aReportingChannel, aURI, aRejectedReason);
|
||||
}
|
||||
|
||||
NotifyAllowDecision(aReportingChannel, aTrackingChannel, aURI, nullptr);
|
||||
}
|
||||
|
||||
// Send a message to notify OnContentBlockingEvent in the parent, which will
|
||||
// update the ContentBlockingLog in the parent.
|
||||
void NotifyEventInChild(
|
||||
nsPIDOMWindowOuter* aWindow, nsIChannel* aReportingChannel,
|
||||
nsIChannel* aTrackingChannel, bool aBlocked, uint32_t aRejectedReason,
|
||||
const nsACString& aTrackingOrigin,
|
||||
const Maybe<ContentBlockingNotifier::StorageAccessGrantedReason>& aReason) {
|
||||
MOZ_ASSERT(XRE_IsContentProcess());
|
||||
MOZ_ASSERT(aWindow);
|
||||
|
||||
RefPtr<dom::BrowserChild> browserChild = dom::BrowserChild::GetFrom(aWindow);
|
||||
NS_ENSURE_TRUE_VOID(browserChild);
|
||||
|
||||
nsTArray<nsCString> trackingFullHashes;
|
||||
nsCOMPtr<nsIClassifiedChannel> classifiedChannel =
|
||||
do_QueryInterface(aTrackingChannel);
|
||||
|
||||
if (classifiedChannel) {
|
||||
Unused << classifiedChannel->GetMatchedTrackingFullHashes(
|
||||
trackingFullHashes);
|
||||
}
|
||||
|
||||
browserChild->NotifyContentBlockingEvent(aRejectedReason, aReportingChannel,
|
||||
aBlocked, aTrackingOrigin,
|
||||
trackingFullHashes, aReason);
|
||||
}
|
||||
|
||||
// Update the ContentBlockingLog of the top-level WindowGlobalParent of
|
||||
// the reporting channel.
|
||||
void NotifyEventInParent(
|
||||
nsIChannel* aReportingChannel, nsIChannel* aTrackingChannel, bool aBlocked,
|
||||
uint32_t aRejectedReason, const nsACString& aTrackingOrigin,
|
||||
const Maybe<ContentBlockingNotifier::StorageAccessGrantedReason>& aReason) {
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
|
||||
nsCOMPtr<nsILoadInfo> loadInfo = aReportingChannel->LoadInfo();
|
||||
RefPtr<dom::BrowsingContext> bc;
|
||||
loadInfo->GetBrowsingContext(getter_AddRefs(bc));
|
||||
|
||||
if (!bc || bc->IsDiscarded()) {
|
||||
return;
|
||||
}
|
||||
|
||||
bc = bc->Top();
|
||||
RefPtr<dom::WindowGlobalParent> wgp =
|
||||
bc->Canonical()->GetCurrentWindowGlobal();
|
||||
NS_ENSURE_TRUE_VOID(wgp);
|
||||
|
||||
nsTArray<nsCString> trackingFullHashes;
|
||||
nsCOMPtr<nsIClassifiedChannel> classifiedChannel =
|
||||
do_QueryInterface(aTrackingChannel);
|
||||
|
||||
if (classifiedChannel) {
|
||||
Unused << classifiedChannel->GetMatchedTrackingFullHashes(
|
||||
trackingFullHashes);
|
||||
}
|
||||
|
||||
wgp->NotifyContentBlockingEvent(aRejectedReason, aReportingChannel, aBlocked,
|
||||
aTrackingOrigin, trackingFullHashes, aReason);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
/* static */ void ContentBlockingNotifier::ReportUnblockingToConsole(
|
||||
nsPIDOMWindowInner* aWindow, const nsAString& aTrackingOrigin,
|
||||
ContentBlockingNotifier::StorageAccessGrantedReason aReason) {
|
||||
nsCOMPtr<nsIPrincipal> principal =
|
||||
nsGlobalWindowInner::Cast(aWindow)->GetPrincipal();
|
||||
if (NS_WARN_IF(!principal)) {
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<Document> doc = aWindow->GetExtantDoc();
|
||||
if (NS_WARN_IF(!doc)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoString trackingOrigin(aTrackingOrigin);
|
||||
|
||||
nsAutoString sourceLine;
|
||||
uint32_t lineNumber = 0, columnNumber = 0;
|
||||
JSContext* cx = nsContentUtils::GetCurrentJSContext();
|
||||
if (cx) {
|
||||
nsJSUtils::GetCallingLocation(cx, sourceLine, &lineNumber, &columnNumber);
|
||||
}
|
||||
|
||||
RefPtr<Runnable> runnable = NS_NewRunnableFunction(
|
||||
"ReportUnblockingToConsoleDelayed",
|
||||
[doc, principal, trackingOrigin, sourceLine, lineNumber, columnNumber,
|
||||
aReason]() {
|
||||
nsAutoString origin;
|
||||
nsresult rv = nsContentUtils::GetUTFOrigin(principal, origin);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Not adding grantedOrigin yet because we may not want it later.
|
||||
AutoTArray<nsString, 3> params = {origin, trackingOrigin};
|
||||
const char* messageWithSameOrigin = nullptr;
|
||||
|
||||
switch (aReason) {
|
||||
case ContentBlockingNotifier::eStorageAccessAPI:
|
||||
messageWithSameOrigin = "CookieAllowedForTrackerByStorageAccessAPI";
|
||||
break;
|
||||
|
||||
case ContentBlockingNotifier::eOpenerAfterUserInteraction:
|
||||
[[fallthrough]];
|
||||
case ContentBlockingNotifier::eOpener:
|
||||
messageWithSameOrigin = "CookieAllowedForTrackerByHeuristic";
|
||||
break;
|
||||
}
|
||||
|
||||
nsContentUtils::ReportToConsole(
|
||||
nsIScriptError::warningFlag, ANTITRACKING_CONSOLE_CATEGORY, doc,
|
||||
nsContentUtils::eNECKO_PROPERTIES, messageWithSameOrigin, params,
|
||||
nullptr, sourceLine, lineNumber, columnNumber);
|
||||
});
|
||||
|
||||
RunConsoleReportingRunnable(runnable.forget());
|
||||
}
|
||||
|
||||
/* static */
|
||||
void ContentBlockingNotifier::OnDecision(nsIChannel* aChannel,
|
||||
BlockingDecision aDecision,
|
||||
uint32_t aRejectedReason) {
|
||||
MOZ_ASSERT(
|
||||
aRejectedReason == 0 ||
|
||||
aRejectedReason ==
|
||||
nsIWebProgressListener::STATE_COOKIES_BLOCKED_BY_PERMISSION ||
|
||||
aRejectedReason ==
|
||||
nsIWebProgressListener::STATE_COOKIES_BLOCKED_TRACKER ||
|
||||
aRejectedReason ==
|
||||
nsIWebProgressListener::STATE_COOKIES_BLOCKED_SOCIALTRACKER ||
|
||||
aRejectedReason ==
|
||||
nsIWebProgressListener::STATE_COOKIES_PARTITIONED_FOREIGN ||
|
||||
aRejectedReason == nsIWebProgressListener::STATE_COOKIES_BLOCKED_ALL ||
|
||||
aRejectedReason == nsIWebProgressListener::STATE_COOKIES_BLOCKED_FOREIGN);
|
||||
MOZ_ASSERT(aDecision == BlockingDecision::eBlock ||
|
||||
aDecision == BlockingDecision::eAllow);
|
||||
|
||||
if (!aChannel) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
aChannel->GetURI(getter_AddRefs(uri));
|
||||
|
||||
// Can be called in EITHER the parent or child process.
|
||||
// Window is only needed while in child processes.
|
||||
if (XRE_IsParentProcess()) {
|
||||
NotifyBlockingDecision(aChannel, aChannel, aDecision, aRejectedReason, uri);
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(XRE_IsContentProcess());
|
||||
|
||||
nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil = services::GetThirdPartyUtil();
|
||||
if (!thirdPartyUtil) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> uriBeingLoaded =
|
||||
AntiTrackingCommon::MaybeGetDocumentURIBeingLoaded(aChannel);
|
||||
nsCOMPtr<mozIDOMWindowProxy> win;
|
||||
nsresult rv = thirdPartyUtil->GetTopWindowForChannel(aChannel, uriBeingLoaded,
|
||||
getter_AddRefs(win));
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowOuter> pwin = nsPIDOMWindowOuter::From(win);
|
||||
if (!pwin) {
|
||||
return;
|
||||
}
|
||||
|
||||
NotifyBlockingDecision(aChannel, aChannel, aDecision, aRejectedReason, uri,
|
||||
pwin);
|
||||
}
|
||||
|
||||
/* static */
|
||||
void ContentBlockingNotifier::OnDecision(nsPIDOMWindowInner* aWindow,
|
||||
BlockingDecision aDecision,
|
||||
uint32_t aRejectedReason) {
|
||||
MOZ_ASSERT(aWindow);
|
||||
MOZ_ASSERT(
|
||||
aRejectedReason == 0 ||
|
||||
aRejectedReason ==
|
||||
nsIWebProgressListener::STATE_COOKIES_BLOCKED_BY_PERMISSION ||
|
||||
aRejectedReason ==
|
||||
nsIWebProgressListener::STATE_COOKIES_BLOCKED_TRACKER ||
|
||||
aRejectedReason ==
|
||||
nsIWebProgressListener::STATE_COOKIES_BLOCKED_SOCIALTRACKER ||
|
||||
aRejectedReason ==
|
||||
nsIWebProgressListener::STATE_COOKIES_PARTITIONED_FOREIGN ||
|
||||
aRejectedReason == nsIWebProgressListener::STATE_COOKIES_BLOCKED_ALL ||
|
||||
aRejectedReason == nsIWebProgressListener::STATE_COOKIES_BLOCKED_FOREIGN);
|
||||
MOZ_ASSERT(aDecision == BlockingDecision::eBlock ||
|
||||
aDecision == BlockingDecision::eAllow);
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowOuter> pwin = AntiTrackingUtils::GetTopWindow(aWindow);
|
||||
if (!pwin) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsPIDOMWindowInner* inner = pwin->GetCurrentInnerWindow();
|
||||
if (!inner) {
|
||||
return;
|
||||
}
|
||||
Document* pwinDoc = inner->GetExtantDoc();
|
||||
if (!pwinDoc) {
|
||||
return;
|
||||
}
|
||||
nsIChannel* channel = pwinDoc->GetChannel();
|
||||
if (!channel) {
|
||||
return;
|
||||
}
|
||||
|
||||
Document* document = aWindow->GetExtantDoc();
|
||||
if (!document) {
|
||||
return;
|
||||
}
|
||||
nsIURI* uri = document->GetDocumentURI();
|
||||
nsIChannel* trackingChannel = document->GetChannel();
|
||||
|
||||
NotifyBlockingDecision(channel, trackingChannel, aDecision, aRejectedReason,
|
||||
uri, pwin);
|
||||
}
|
||||
|
||||
/* static */
|
||||
void ContentBlockingNotifier::OnEvent(nsIChannel* aChannel,
|
||||
uint32_t aRejectedReason) {
|
||||
MOZ_ASSERT(XRE_IsParentProcess() && aChannel);
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
aChannel->GetURI(getter_AddRefs(uri));
|
||||
|
||||
nsAutoCString trackingOrigin;
|
||||
if (uri) {
|
||||
Unused << nsContentUtils::GetASCIIOrigin(uri, trackingOrigin);
|
||||
}
|
||||
|
||||
return ContentBlockingNotifier::OnEvent(nullptr, aChannel, aChannel, true,
|
||||
aRejectedReason, trackingOrigin);
|
||||
}
|
||||
|
||||
/* static */
|
||||
void ContentBlockingNotifier::OnEvent(
|
||||
nsPIDOMWindowOuter* aWindow, nsIChannel* aReportingChannel,
|
||||
nsIChannel* aTrackingChannel, bool aBlocked, uint32_t aRejectedReason,
|
||||
const nsACString& aTrackingOrigin,
|
||||
const Maybe<StorageAccessGrantedReason>& aReason) {
|
||||
if (XRE_IsParentProcess()) {
|
||||
NotifyEventInParent(aReportingChannel, aTrackingChannel, aBlocked,
|
||||
aRejectedReason, aTrackingOrigin, aReason);
|
||||
} else {
|
||||
NotifyEventInChild(aWindow, aReportingChannel, aTrackingChannel, aBlocked,
|
||||
aRejectedReason, aTrackingOrigin, aReason);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
/* -*- 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_contentblockingnotifier_h
|
||||
#define mozilla_contentblockingnotifier_h
|
||||
|
||||
#include "nsStringFwd.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
|
||||
#define ANTITRACKING_CONSOLE_CATEGORY NS_LITERAL_CSTRING("Content Blocking")
|
||||
|
||||
class nsIChannel;
|
||||
class nsPIDOMWindowInner;
|
||||
class nsPIDOMWindowOuter;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class ContentBlockingNotifier final {
|
||||
public:
|
||||
enum class BlockingDecision {
|
||||
eBlock,
|
||||
eAllow,
|
||||
};
|
||||
enum StorageAccessGrantedReason {
|
||||
eStorageAccessAPI,
|
||||
eOpenerAfterUserInteraction,
|
||||
eOpener
|
||||
};
|
||||
|
||||
// This method can be called on the parent process or on the content process.
|
||||
// The notification is propagated to the child channel if aChannel is a parent
|
||||
// channel proxy.
|
||||
//
|
||||
// aDecision can be eBlock if we have decided to block some content, or eAllow
|
||||
// if we have decided to allow the content through.
|
||||
//
|
||||
// aRejectedReason must be one of these values:
|
||||
// * nsIWebProgressListener::STATE_COOKIES_BLOCKED_BY_PERMISSION
|
||||
// * nsIWebProgressListener::STATE_COOKIES_BLOCKED_TRACKER
|
||||
// * nsIWebProgressListener::STATE_COOKIES_BLOCKED_SOCIALTRACKER
|
||||
// * nsIWebProgressListener::STATE_COOKIES_BLOCKED_ALL
|
||||
// * nsIWebProgressListener::STATE_COOKIES_BLOCKED_FOREIGN
|
||||
static void OnDecision(nsIChannel* aChannel, BlockingDecision aDecision,
|
||||
uint32_t aRejectedReason);
|
||||
|
||||
static void OnDecision(nsPIDOMWindowInner* aWindow,
|
||||
BlockingDecision aDecision, uint32_t aRejectedReason);
|
||||
|
||||
static void OnEvent(nsIChannel* aChannel, uint32_t aRejectedReason);
|
||||
|
||||
static void OnEvent(
|
||||
nsPIDOMWindowOuter* aWindow, nsIChannel* aReportingChannel,
|
||||
nsIChannel* aTrackingChannel, bool aBlocked, uint32_t aRejectedReason,
|
||||
const nsACString& aTrackingOrigin,
|
||||
const Maybe<StorageAccessGrantedReason>& aReason = Nothing());
|
||||
|
||||
static void ReportUnblockingToConsole(nsPIDOMWindowInner* aWindow,
|
||||
const nsAString& aTrackingOrigin,
|
||||
StorageAccessGrantedReason aReason);
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_contentblockingnotifier_h
|
|
@ -300,16 +300,16 @@ bool StorageDisabledByAntiTracking(nsPIDOMWindowInner* aWindow,
|
|||
bool disabled = StorageDisabledByAntiTrackingInternal(
|
||||
aWindow, aChannel, aPrincipal, aURI, cookieJarSettings, aRejectedReason);
|
||||
if (aWindow) {
|
||||
AntiTrackingCommon::NotifyBlockingDecision(
|
||||
ContentBlockingNotifier::OnDecision(
|
||||
aWindow,
|
||||
disabled ? AntiTrackingCommon::BlockingDecision::eBlock
|
||||
: AntiTrackingCommon::BlockingDecision::eAllow,
|
||||
disabled ? ContentBlockingNotifier::BlockingDecision::eBlock
|
||||
: ContentBlockingNotifier::BlockingDecision::eAllow,
|
||||
aRejectedReason);
|
||||
} else if (aChannel) {
|
||||
AntiTrackingCommon::NotifyBlockingDecision(
|
||||
ContentBlockingNotifier::OnDecision(
|
||||
aChannel,
|
||||
disabled ? AntiTrackingCommon::BlockingDecision::eBlock
|
||||
: AntiTrackingCommon::BlockingDecision::eAllow,
|
||||
disabled ? ContentBlockingNotifier::BlockingDecision::eBlock
|
||||
: ContentBlockingNotifier::BlockingDecision::eAllow,
|
||||
aRejectedReason);
|
||||
}
|
||||
return disabled;
|
||||
|
|
|
@ -34,6 +34,7 @@ EXPORTS.mozilla = [
|
|||
'AntiTrackingCommon.h',
|
||||
'AntiTrackingIPCUtils.h',
|
||||
'ContentBlockingAllowList.h',
|
||||
'ContentBlockingNotifier.h',
|
||||
'StorageAccess.h',
|
||||
'StoragePrincipalHelper.h',
|
||||
'URLDecorationStripper.h',
|
||||
|
@ -41,7 +42,9 @@ EXPORTS.mozilla = [
|
|||
|
||||
UNIFIED_SOURCES += [
|
||||
'AntiTrackingCommon.cpp',
|
||||
'AntiTrackingUtils.cpp',
|
||||
'ContentBlockingAllowList.cpp',
|
||||
'ContentBlockingNotifier.cpp',
|
||||
'SettingsChangeObserver.cpp',
|
||||
'StorageAccess.cpp',
|
||||
'StoragePrincipalHelper.cpp',
|
||||
|
|
Загрузка…
Ссылка в новой задаче