Bug 1493563 - Part 2: Record a log of content blocking actions on each top-level document; r=baku

Differential Revision: https://phabricator.services.mozilla.com/D6592
This commit is contained in:
Ehsan Akhgari 2018-09-22 17:04:38 -04:00
parent 6c0983c7d8
commit 9a26b7fd29
7 changed files with 117 additions and 17 deletions

View File

@ -0,0 +1,53 @@
/* -*- 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_dom_ContentBlockingLog_h
#define mozilla_dom_ContentBlockingLog_h
#include "mozilla/Pair.h"
#include "mozilla/UniquePtr.h"
#include "nsClassHashtable.h"
#include "nsHashKeys.h"
#include "nsTArray.h"
namespace mozilla {
namespace dom {
class ContentBlockingLog final
{
// Each element is a pair of (type, blocked). The type values come from the
// blocking types defined in nsIWebProgressListener.
typedef nsTArray<mozilla::Pair<uint32_t, bool>> OriginLog;
public:
ContentBlockingLog() = default;
~ContentBlockingLog() = default;
void RecordLog(const nsAString& aOrigin, uint32_t aType, bool aBlocked)
{
if (aOrigin.IsVoid()) {
return;
}
auto entry = mLog.LookupForAdd(aOrigin);
if (entry) {
entry.Data()->AppendElement(mozilla::MakePair(aType, aBlocked));
} else {
entry.OrInsert([=] {
auto log(MakeUnique<OriginLog>());
log->AppendElement(mozilla::MakePair(aType, aBlocked));
return log.release();
});
}
}
private:
nsClassHashtable<nsStringHashKey, OriginLog> mLog;
};
} // namespace dom
} // namespace mozilla
#endif

View File

@ -153,6 +153,7 @@ EXPORTS.mozilla.dom += [
'ChromeNodeList.h',
'ChromeUtils.h',
'Comment.h',
'ContentBlockingLog.h',
'ContentFrameMessageManager.h',
'ContentProcessMessageManager.h',
'CustomElementRegistry.h',

View File

@ -5281,7 +5281,8 @@ nsGlobalWindowOuter::FirePopupBlockedEvent(nsIDocument* aDoc,
void
nsGlobalWindowOuter::NotifyContentBlockingState(unsigned aState,
nsIChannel* aChannel)
nsIChannel* aChannel,
nsIURI* aURIHint)
{
nsCOMPtr<nsIDocShell> docShell = GetDocShell();
if (!docShell) {
@ -5310,18 +5311,23 @@ nsGlobalWindowOuter::NotifyContentBlockingState(unsigned aState,
return;
}
securityUI->GetState(&state);
nsAutoString origin;
origin.SetIsVoid(true);
if (aURIHint) {
nsContentUtils::GetUTFOrigin(aURIHint, origin);
}
if (aState == nsIWebProgressListener::STATE_BLOCKED_TRACKING_CONTENT) {
doc->SetHasTrackingContentBlocked(true);
doc->SetHasTrackingContentBlocked(true, origin);
} else if (aState == nsIWebProgressListener::STATE_BLOCKED_SLOW_TRACKING_CONTENT) {
doc->SetHasSlowTrackingContentBlocked(true);
doc->SetHasSlowTrackingContentBlocked(true, origin);
} else if (aState == nsIWebProgressListener::STATE_COOKIES_BLOCKED_BY_PERMISSION) {
doc->SetHasCookiesBlockedByPermission(true);
doc->SetHasCookiesBlockedByPermission(true, origin);
} else if (aState == nsIWebProgressListener::STATE_COOKIES_BLOCKED_TRACKER) {
doc->SetHasTrackingCookiesBlocked(true);
doc->SetHasTrackingCookiesBlocked(true, origin);
} else if (aState == nsIWebProgressListener::STATE_COOKIES_BLOCKED_ALL) {
doc->SetHasAllCookiesBlocked(true);
doc->SetHasAllCookiesBlocked(true, origin);
} else if (aState == nsIWebProgressListener::STATE_COOKIES_BLOCKED_FOREIGN) {
doc->SetHasForeignCookiesBlocked(true);
doc->SetHasForeignCookiesBlocked(true, origin);
} else {
// Ignore nsIWebProgressListener::STATE_BLOCKED_UNSAFE_CONTENT;
}

View File

@ -484,7 +484,8 @@ public:
virtual void
NotifyContentBlockingState(unsigned aState,
nsIChannel* aChannel) override;
nsIChannel* aChannel,
nsIURI* aURIHint) override;
virtual uint32_t GetSerial() override {
return mSerial;

View File

@ -7,6 +7,7 @@
#define nsIDocument_h___
#include "mozilla/FlushType.h" // for enum
#include "mozilla/Pair.h" // for Pair
#include "nsAutoPtr.h" // for member
#include "nsCOMArray.h" // for member
#include "nsCompatibility.h" // for member
@ -29,6 +30,7 @@
#include "nsIServiceManager.h"
#include "nsIURI.h" // for use in inline functions
#include "nsIUUIDGenerator.h"
#include "nsIWebProgressListener.h" // for nsIWebProgressListener
#include "nsPIDOMWindow.h" // for use in inline functions
#include "nsPropertyTable.h" // for member
#include "nsStringFwd.h"
@ -43,6 +45,7 @@
#include "nsExpirationTracker.h"
#include "nsClassHashtable.h"
#include "mozilla/CORSMode.h"
#include "mozilla/dom/ContentBlockingLog.h"
#include "mozilla/dom/DispatcherTrait.h"
#include "mozilla/dom/DocumentOrShadowRoot.h"
#include "mozilla/EnumSet.h"
@ -1027,49 +1030,73 @@ public:
/**
* Set the tracking content blocked flag for this document.
*/
void SetHasTrackingContentBlocked(bool aHasTrackingContentBlocked)
void SetHasTrackingContentBlocked(bool aHasTrackingContentBlocked,
const nsAString& aOriginBlocked)
{
mHasTrackingContentBlocked = aHasTrackingContentBlocked;
RecordContentBlockingLog(aOriginBlocked,
nsIWebProgressListener::STATE_BLOCKED_TRACKING_CONTENT,
aHasTrackingContentBlocked);
}
/**
* Set the slow tracking content blocked flag for this document.
*/
void SetHasSlowTrackingContentBlocked(bool aHasSlowTrackingContentBlocked)
void SetHasSlowTrackingContentBlocked(bool aHasSlowTrackingContentBlocked,
const nsAString& aOriginBlocked)
{
mHasSlowTrackingContentBlocked = aHasSlowTrackingContentBlocked;
RecordContentBlockingLog(aOriginBlocked,
nsIWebProgressListener::STATE_BLOCKED_SLOW_TRACKING_CONTENT,
aHasSlowTrackingContentBlocked);
}
/**
* Set the all cookies blocked flag for this document.
*/
void SetHasAllCookiesBlocked(bool aHasAllCookiesBlocked)
void SetHasAllCookiesBlocked(bool aHasAllCookiesBlocked,
const nsAString& aOriginBlocked)
{
mHasAllCookiesBlocked = aHasAllCookiesBlocked;
RecordContentBlockingLog(aOriginBlocked,
nsIWebProgressListener::STATE_COOKIES_BLOCKED_ALL,
aHasAllCookiesBlocked);
}
/**
* Set the tracking cookies blocked flag for this document.
*/
void SetHasTrackingCookiesBlocked(bool aHasTrackingCookiesBlocked)
void SetHasTrackingCookiesBlocked(bool aHasTrackingCookiesBlocked,
const nsAString& aOriginBlocked)
{
mHasTrackingCookiesBlocked = aHasTrackingCookiesBlocked;
RecordContentBlockingLog(aOriginBlocked,
nsIWebProgressListener::STATE_COOKIES_BLOCKED_TRACKER,
aHasTrackingCookiesBlocked);
}
/**
* Set the third-party cookies blocked flag for this document.
*/
void SetHasForeignCookiesBlocked(bool aHasForeignCookiesBlocked)
void SetHasForeignCookiesBlocked(bool aHasForeignCookiesBlocked,
const nsAString& aOriginBlocked)
{
mHasForeignCookiesBlocked = aHasForeignCookiesBlocked;
RecordContentBlockingLog(aOriginBlocked,
nsIWebProgressListener::STATE_COOKIES_BLOCKED_FOREIGN,
aHasForeignCookiesBlocked);
}
/**
* Set the cookies blocked by site permission flag for this document.
*/
void SetHasCookiesBlockedByPermission(bool aHasCookiesBlockedByPermission)
void SetHasCookiesBlockedByPermission(bool aHasCookiesBlockedByPermission,
const nsAString& aOriginBlocked)
{
mHasCookiesBlockedByPermission = aHasCookiesBlockedByPermission;
RecordContentBlockingLog(aOriginBlocked,
nsIWebProgressListener::STATE_COOKIES_BLOCKED_BY_PERMISSION,
aHasCookiesBlockedByPermission);
}
/**
@ -3850,6 +3877,12 @@ protected:
bool aUpdateCSSLoader);
private:
void RecordContentBlockingLog(const nsAString& aOrigin,
uint32_t aType, bool aBlocked)
{
mContentBlockingLog.RecordLog(aOrigin, aType, aBlocked);
}
mutable std::bitset<eDeprecatedOperationCount> mDeprecationWarnedAbout;
mutable std::bitset<eDocumentWarningCount> mDocWarningWarnedAbout;
@ -4519,6 +4552,11 @@ protected:
// existing in the set means the corresponding script isn't a tracking script.
nsTHashtable<nsCStringHashKey> mTrackingScripts;
// The log of all content blocking actions taken on this document. This is only
// stored on top-level documents and includes the activity log for all of the
// nested subdocuments as well.
mozilla::dom::ContentBlockingLog mContentBlockingLog;
// List of ancestor principals. This is set at the point a document
// is connected to a docshell and not mutated thereafter.
nsTArray<nsCOMPtr<nsIPrincipal>> mAncestorPrincipals;

View File

@ -1094,7 +1094,8 @@ public:
virtual void
NotifyContentBlockingState(unsigned aState,
nsIChannel* aChannel) = 0;
nsIChannel* aChannel,
nsIURI* aURIHint = nullptr) = 0;
// WebIDL-ish APIs
void MarkUncollectableForCCGeneration(uint32_t aGeneration)

View File

@ -1089,7 +1089,7 @@ AntiTrackingCommon::NotifyRejection(nsIChannel* aChannel,
nsCOMPtr<nsIURI> uri;
aChannel->GetURI(getter_AddRefs(uri));
pwin->NotifyContentBlockingState(aRejectedReason, aChannel);
pwin->NotifyContentBlockingState(aRejectedReason, aChannel, uri);
ReportBlockingToConsole(pwin, uri, aRejectedReason);
}
@ -1128,7 +1128,7 @@ AntiTrackingCommon::NotifyRejection(nsPIDOMWindowInner* aWindow,
nsCOMPtr<nsIURI> uri;
channel->GetURI(getter_AddRefs(uri));
pwin->NotifyContentBlockingState(aRejectedReason, channel);
pwin->NotifyContentBlockingState(aRejectedReason, channel, uri);
ReportBlockingToConsole(pwin, uri, aRejectedReason);
}