зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1522210 - Fingerprinting and cryptomining classifiers must have separate nsIWebProgressListener blocking state codes - part 1 - UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode, r=ehsan
Differential Revision: https://phabricator.services.mozilla.com/D17637
This commit is contained in:
Родитель
325e31df1d
Коммит
43a5f36077
|
@ -62,6 +62,7 @@
|
|||
#include "mozilla/dom/LoadURIOptionsBinding.h"
|
||||
|
||||
#include "mozilla/net/ReferrerPolicy.h"
|
||||
#include "mozilla/net/UrlClassifierFeatureFactory.h"
|
||||
|
||||
#include "nsIApplicationCacheChannel.h"
|
||||
#include "nsIApplicationCacheContainer.h"
|
||||
|
@ -6699,7 +6700,8 @@ nsresult nsDocShell::EndPageLoad(nsIWebProgress* aProgress,
|
|||
// a tracking URL. We make a note of this iframe node by including
|
||||
// it in a dedicated array of blocked tracking nodes under its parent
|
||||
// document. (document of parent window of blocked document)
|
||||
if (isTopFrame == false && aStatus == NS_ERROR_TRACKING_URI) {
|
||||
if (!isTopFrame &&
|
||||
UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(aStatus)) {
|
||||
// frameElement is our nsIContent to be annotated
|
||||
RefPtr<Element> frameElement;
|
||||
nsPIDOMWindowOuter* thisWindow = GetWindow();
|
||||
|
@ -6725,7 +6727,7 @@ nsresult nsDocShell::EndPageLoad(nsIWebProgress* aProgress,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
parentDoc->AddBlockedTrackingNode(frameElement);
|
||||
parentDoc->AddBlockedNodeByClassifier(frameElement);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "mozilla/dom/ReportingHeader.h"
|
||||
#include "mozilla/dom/UnionTypes.h"
|
||||
#include "mozilla/dom/WindowBinding.h" // For IdleRequestCallback/Options
|
||||
#include "mozilla/net/UrlClassifierFeatureFactory.h"
|
||||
#include "IOActivityMonitor.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "mozJSComponentLoader.h"
|
||||
|
@ -833,5 +834,11 @@ constexpr auto kSkipSelfHosted = JS::SavedFrameSelfHosted::Exclude;
|
|||
service->RegisterWindowActor(aName, aOptions, aRv);
|
||||
}
|
||||
|
||||
/* static */ bool ChromeUtils::IsClassifierBlockingErrorCode(
|
||||
GlobalObject& aGlobal, uint32_t aError) {
|
||||
return net::UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(
|
||||
static_cast<nsresult>(aError));
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -179,6 +179,9 @@ class ChromeUtils {
|
|||
const nsAString& aName,
|
||||
const WindowActorOptions& aOptions,
|
||||
ErrorResult& aRv);
|
||||
|
||||
static bool IsClassifierBlockingErrorCode(GlobalObject& aGlobal,
|
||||
uint32_t aError);
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -5396,14 +5396,15 @@ void Document::ResolveScheduledSVGPresAttrs() {
|
|||
mLazySVGPresElements.Clear();
|
||||
}
|
||||
|
||||
already_AddRefed<nsSimpleContentList> Document::BlockedTrackingNodes() const {
|
||||
already_AddRefed<nsSimpleContentList> Document::BlockedNodesByClassifier()
|
||||
const {
|
||||
RefPtr<nsSimpleContentList> list = new nsSimpleContentList(nullptr);
|
||||
|
||||
nsTArray<nsWeakPtr> blockedTrackingNodes;
|
||||
blockedTrackingNodes = mBlockedTrackingNodes;
|
||||
nsTArray<nsWeakPtr> blockedNodes;
|
||||
blockedNodes = mBlockedNodesByClassifier;
|
||||
|
||||
for (unsigned long i = 0; i < blockedTrackingNodes.Length(); i++) {
|
||||
nsWeakPtr weakNode = blockedTrackingNodes[i];
|
||||
for (unsigned long i = 0; i < blockedNodes.Length(); i++) {
|
||||
nsWeakPtr weakNode = blockedNodes[i];
|
||||
nsCOMPtr<nsIContent> node = do_QueryReferent(weakNode);
|
||||
// Consider only nodes to which we have managed to get strong references.
|
||||
// Coping with nullptrs since it's expected for nodes to disappear when
|
||||
|
|
|
@ -1370,33 +1370,33 @@ class Document : public nsINode,
|
|||
mozilla::Maybe<mozilla::dom::ClientState> GetClientState() const;
|
||||
mozilla::Maybe<mozilla::dom::ServiceWorkerDescriptor> GetController() const;
|
||||
|
||||
// Returns the size of the mBlockedTrackingNodes array.
|
||||
// Returns the size of the mBlockedNodesByClassifier array.
|
||||
//
|
||||
// This array contains nodes that have been blocked to prevent
|
||||
// user tracking. They most likely have had their nsIChannel
|
||||
// canceled by the URL classifier (Safebrowsing).
|
||||
// This array contains nodes that have been blocked to prevent user tracking,
|
||||
// fingerprinting, cryptomining, etc. They most likely have had their
|
||||
// nsIChannel canceled by the URL classifier (Safebrowsing).
|
||||
//
|
||||
// A script can subsequently use GetBlockedTrackingNodes()
|
||||
// A script can subsequently use GetBlockedNodesByClassifier()
|
||||
// to get a list of references to these nodes.
|
||||
//
|
||||
// Note:
|
||||
// This expresses how many tracking nodes have been blocked for this
|
||||
// document since its beginning, not how many of them are still around
|
||||
// in the DOM tree. Weak references to blocked nodes are added in the
|
||||
// mBlockedTrackingNodesArray but they are not removed when those nodes
|
||||
// are removed from the tree or even garbage collected.
|
||||
long BlockedTrackingNodeCount() const {
|
||||
return mBlockedTrackingNodes.Length();
|
||||
// This expresses how many tracking nodes have been blocked for this document
|
||||
// since its beginning, not how many of them are still around in the DOM tree.
|
||||
// Weak references to blocked nodes are added in the mBlockedNodesByClassifier
|
||||
// array but they are not removed when those nodes are removed from the tree
|
||||
// or even garbage collected.
|
||||
long BlockedNodeByClassifierCount() const {
|
||||
return mBlockedNodesByClassifier.Length();
|
||||
}
|
||||
|
||||
//
|
||||
// Returns strong references to mBlockedTrackingNodes. (Document.h)
|
||||
// Returns strong references to mBlockedNodesByClassifier. (Document.h)
|
||||
//
|
||||
// This array contains nodes that have been blocked to prevent
|
||||
// user tracking. They most likely have had their nsIChannel
|
||||
// canceled by the URL classifier (Safebrowsing).
|
||||
//
|
||||
already_AddRefed<nsSimpleContentList> BlockedTrackingNodes() const;
|
||||
already_AddRefed<nsSimpleContentList> BlockedNodesByClassifier() const;
|
||||
|
||||
// Helper method that returns true if the document has storage-access sandbox
|
||||
// flag.
|
||||
|
@ -3248,10 +3248,10 @@ class Document : public nsINode,
|
|||
|
||||
/*
|
||||
* Given a node, get a weak reference to it and append that reference to
|
||||
* mBlockedTrackingNodes. Can be used later on to look up a node in it.
|
||||
* mBlockedNodesByClassifier. Can be used later on to look up a node in it.
|
||||
* (e.g., by the UI)
|
||||
*/
|
||||
void AddBlockedTrackingNode(nsINode* node) {
|
||||
void AddBlockedNodeByClassifier(nsINode* node) {
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
|
@ -3259,7 +3259,7 @@ class Document : public nsINode,
|
|||
nsWeakPtr weakNode = do_GetWeakReference(node);
|
||||
|
||||
if (weakNode) {
|
||||
mBlockedTrackingNodes.AppendElement(weakNode);
|
||||
mBlockedNodesByClassifier.AppendElement(weakNode);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4248,7 +4248,7 @@ class Document : public nsINode,
|
|||
// classifier. (Safebrowsing)
|
||||
//
|
||||
// Weak nsINode pointers are used to allow nodes to disappear.
|
||||
nsTArray<nsWeakPtr> mBlockedTrackingNodes;
|
||||
nsTArray<nsWeakPtr> mBlockedNodesByClassifier;
|
||||
|
||||
// Weak reference to mScriptGlobalObject QI:d to nsPIDOMWindow,
|
||||
// updated on every set of mScriptGlobalObject.
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/ImageTracker.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "mozilla/net/UrlClassifierFeatureFactory.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
|
||||
#ifdef LoadImage
|
||||
|
@ -184,16 +185,18 @@ nsImageLoadingContent::Notify(imgIRequest* aRequest, int32_t aType,
|
|||
nsresult errorCode = NS_OK;
|
||||
aRequest->GetImageErrorCode(&errorCode);
|
||||
|
||||
/* Handle image not loading error because source was a tracking URL.
|
||||
/* Handle image not loading error because source was a tracking URL (or
|
||||
* fingerprinting, cryptomining, etc).
|
||||
* We make a note of this image node by including it in a dedicated
|
||||
* array of blocked tracking nodes under its parent document.
|
||||
*/
|
||||
if (errorCode == NS_ERROR_TRACKING_URI) {
|
||||
if (net::UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(
|
||||
errorCode)) {
|
||||
nsCOMPtr<nsIContent> thisNode =
|
||||
do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
|
||||
|
||||
Document* doc = GetOurOwnerDoc();
|
||||
doc->AddBlockedTrackingNode(thisNode);
|
||||
doc->AddBlockedNodeByClassifier(thisNode);
|
||||
}
|
||||
}
|
||||
nsresult status =
|
||||
|
|
|
@ -90,6 +90,7 @@
|
|||
#include "mozilla/dom/HTMLObjectElementBinding.h"
|
||||
#include "mozilla/dom/HTMLEmbedElement.h"
|
||||
#include "mozilla/dom/HTMLObjectElement.h"
|
||||
#include "mozilla/net/UrlClassifierFeatureFactory.h"
|
||||
#include "mozilla/LoadInfo.h"
|
||||
#include "nsChannelClassifier.h"
|
||||
#include "nsFocusManager.h"
|
||||
|
@ -993,7 +994,7 @@ nsObjectLoadingContent::OnStartRequest(nsIRequest* aRequest,
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (status == NS_ERROR_TRACKING_URI) {
|
||||
if (UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(status)) {
|
||||
mContentBlockingEnabled = true;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -1017,14 +1018,15 @@ nsObjectLoadingContent::OnStopRequest(nsIRequest* aRequest,
|
|||
nsresult aStatusCode) {
|
||||
AUTO_PROFILER_LABEL("nsObjectLoadingContent::OnStopRequest", NETWORK);
|
||||
|
||||
// Handle object not loading error because source was a tracking URL.
|
||||
// Handle object not loading error because source was a tracking URL (or
|
||||
// fingerprinting, cryptomining, etc.).
|
||||
// We make a note of this object node by including it in a dedicated
|
||||
// array of blocked tracking nodes under its parent document.
|
||||
if (aStatusCode == NS_ERROR_TRACKING_URI) {
|
||||
if (UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(aStatusCode)) {
|
||||
nsCOMPtr<nsIContent> thisNode =
|
||||
do_QueryInterface(static_cast<nsIObjectLoadingContent*>(this));
|
||||
if (thisNode && thisNode->IsInComposedDoc()) {
|
||||
thisNode->GetComposedDoc()->AddBlockedTrackingNode(thisNode);
|
||||
thisNode->GetComposedDoc()->AddBlockedNodeByClassifier(thisNode);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -391,6 +391,10 @@ partial namespace ChromeUtils {
|
|||
|
||||
[ChromeOnly, Throws]
|
||||
void registerWindowActor(DOMString aName, WindowActorOptions aOptions);
|
||||
|
||||
[ChromeOnly]
|
||||
// aError should a nsresult.
|
||||
boolean isClassifierBlockingErrorCode(unsigned long aError);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -79,6 +79,7 @@
|
|||
#include "mozilla/dom/VideoTrackList.h"
|
||||
#include "mozilla/dom/WakeLock.h"
|
||||
#include "mozilla/dom/power/PowerManagerService.h"
|
||||
#include "mozilla/net/UrlClassifierFeatureFactory.h"
|
||||
#include "nsAttrValueInlines.h"
|
||||
#include "nsContentPolicyUtils.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
@ -639,13 +640,15 @@ HTMLMediaElement::MediaLoadListener::OnStartRequest(nsIRequest* aRequest,
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (NS_FAILED(status)) {
|
||||
if (element) {
|
||||
// Handle media not loading error because source was a tracking URL.
|
||||
// Handle media not loading error because source was a tracking URL (or
|
||||
// fingerprinting, cryptomining, etc).
|
||||
// We make a note of this media node by including it in a dedicated
|
||||
// array of blocked tracking nodes under its parent document.
|
||||
if (status == NS_ERROR_TRACKING_URI) {
|
||||
if (net::UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(
|
||||
status)) {
|
||||
Document* ownerDoc = element->OwnerDoc();
|
||||
if (ownerDoc) {
|
||||
ownerDoc->AddBlockedTrackingNode(element);
|
||||
ownerDoc->AddBlockedNodeByClassifier(element);
|
||||
}
|
||||
}
|
||||
element->NotifyLoadError(
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "mozilla/dom/SRILogHelper.h"
|
||||
#include "mozilla/net/UrlClassifierFeatureFactory.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsGlobalWindowInner.h"
|
||||
|
@ -3249,8 +3250,9 @@ void ScriptLoader::ReportErrorToConsole(ScriptLoadRequest* aRequest,
|
|||
message = isScript ? "ScriptSourceMalformed" : "ModuleSourceMalformed";
|
||||
} else if (aResult == NS_ERROR_DOM_BAD_URI) {
|
||||
message = isScript ? "ScriptSourceNotAllowed" : "ModuleSourceNotAllowed";
|
||||
} else if (aResult == NS_ERROR_TRACKING_URI) {
|
||||
// Tracking protection errors already show their own console messages.
|
||||
} else if (net::UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(
|
||||
aResult)) {
|
||||
// Blocking classifier error codes already show their own console messages.
|
||||
return;
|
||||
} else {
|
||||
message = isScript ? "ScriptSourceLoadFailed" : "ModuleSourceLoadFailed";
|
||||
|
@ -3285,13 +3287,15 @@ void ScriptLoader::ReportPreloadErrorsToConsole(ScriptLoadRequest* aRequest) {
|
|||
void ScriptLoader::HandleLoadError(ScriptLoadRequest* aRequest,
|
||||
nsresult aResult) {
|
||||
/*
|
||||
* Handle script not loading error because source was a tracking URL.
|
||||
* Handle script not loading error because source was an tracking URL (or
|
||||
* fingerprinting, cryptoming, etc).
|
||||
* We make a note of this script node by including it in a dedicated
|
||||
* array of blocked tracking nodes under its parent document.
|
||||
*/
|
||||
if (aResult == NS_ERROR_TRACKING_URI) {
|
||||
if (net::UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(
|
||||
aResult)) {
|
||||
nsCOMPtr<nsIContent> cont = do_QueryInterface(aRequest->Element());
|
||||
mDocument->AddBlockedTrackingNode(cont);
|
||||
mDocument->AddBlockedNodeByClassifier(cont);
|
||||
}
|
||||
|
||||
if (aRequest->IsModuleRequest() && !aRequest->mIsInline) {
|
||||
|
|
|
@ -61,18 +61,19 @@ interface HTMLDocument : Document {
|
|||
|
||||
partial interface HTMLDocument {
|
||||
/*
|
||||
* Number of nodes that have been blocked by
|
||||
* the Safebrowsing API to prevent tracking.
|
||||
* Number of nodes that have been blocked by the Safebrowsing API to prevent
|
||||
* tracking, cryptomining and so on. This method is for testing only.
|
||||
*/
|
||||
[ChromeOnly, Pure]
|
||||
readonly attribute long blockedTrackingNodeCount;
|
||||
readonly attribute long blockedNodeByClassifierCount;
|
||||
|
||||
/*
|
||||
* List of nodes that have been blocked by
|
||||
* the Safebrowsing API to prevent tracking.
|
||||
* List of nodes that have been blocked by the Safebrowsing API to prevent
|
||||
* tracking, fingerprinting, cryptomining and so on. This method is for
|
||||
* testing only.
|
||||
*/
|
||||
[ChromeOnly, Pure]
|
||||
readonly attribute NodeList blockedTrackingNodes;
|
||||
readonly attribute NodeList blockedNodesByClassifier;
|
||||
|
||||
[ChromeOnly]
|
||||
void userInteractionForTesting();
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include "mozilla/dom/MediaList.h"
|
||||
#include "mozilla/dom/ShadowRoot.h"
|
||||
#include "mozilla/dom/URL.h"
|
||||
#include "mozilla/net/UrlClassifierFeatureFactory.h"
|
||||
#include "mozilla/AsyncEventDispatcher.h"
|
||||
#include "mozilla/ServoBindings.h"
|
||||
#include "mozilla/StyleSheet.h"
|
||||
|
@ -595,20 +596,22 @@ nsresult SheetLoadData::VerifySheetReadyToParse(nsresult aStatus,
|
|||
if (NS_FAILED(aStatus)) {
|
||||
LOG_WARN(
|
||||
(" Load failed: status 0x%" PRIx32, static_cast<uint32_t>(aStatus)));
|
||||
// Handle sheet not loading error because source was a tracking URL.
|
||||
// Handle sheet not loading error because source was a tracking URL (or
|
||||
// fingerprinting, cryptomining, etc).
|
||||
// We make a note of this sheet node by including it in a dedicated
|
||||
// array of blocked tracking nodes under its parent document.
|
||||
//
|
||||
// Multiple sheet load instances might be tied to this request,
|
||||
// we annotate each one linked to a valid owning element (node).
|
||||
if (aStatus == NS_ERROR_TRACKING_URI) {
|
||||
if (net::UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(
|
||||
aStatus)) {
|
||||
Document* doc = mLoader->GetDocument();
|
||||
if (doc) {
|
||||
for (SheetLoadData* data = this; data; data = data->mNext) {
|
||||
// mOwningElement may be null but AddBlockTrackingNode can cope
|
||||
nsCOMPtr<nsIContent> content =
|
||||
do_QueryInterface(data->mOwningElement);
|
||||
doc->AddBlockedTrackingNode(content);
|
||||
doc->AddBlockedNodeByClassifier(content);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "mozilla/net/NeckoChild.h"
|
||||
#include "mozilla/net/HttpChannelChild.h"
|
||||
#include "mozilla/net/UrlClassifierCommon.h"
|
||||
#include "mozilla/net/UrlClassifierFeatureFactory.h"
|
||||
|
||||
#include "AltDataOutputStreamChild.h"
|
||||
#include "CookieServiceChild.h"
|
||||
|
@ -1190,7 +1191,8 @@ void HttpChannelChild::DoOnStopRequest(nsIRequest* aRequest,
|
|||
// NB: We use aChannelStatus here instead of mStatus because if there was an
|
||||
// nsCORSListenerProxy on this request, it will override the tracking
|
||||
// protection's return value.
|
||||
if (aChannelStatus == NS_ERROR_TRACKING_URI ||
|
||||
if (UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(
|
||||
aChannelStatus) ||
|
||||
aChannelStatus == NS_ERROR_MALWARE_URI ||
|
||||
aChannelStatus == NS_ERROR_UNWANTED_URI ||
|
||||
aChannelStatus == NS_ERROR_BLOCKED_URI ||
|
||||
|
|
|
@ -122,6 +122,7 @@
|
|||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/dom/ServiceWorkerUtils.h"
|
||||
#include "mozilla/net/AsyncUrlChannelClassifier.h"
|
||||
#include "mozilla/net/UrlClassifierFeatureFactory.h"
|
||||
|
||||
#ifdef MOZ_TASK_TRACER
|
||||
# include "GeckoTaskTracer.h"
|
||||
|
@ -5990,9 +5991,14 @@ nsHttpChannel::Cancel(nsresult status) {
|
|||
MOZ_ASSERT(NS_IsMainThread());
|
||||
// We should never have a pump open while a CORS preflight is in progress.
|
||||
MOZ_ASSERT_IF(mPreflightChannel, !mCachePump);
|
||||
MOZ_ASSERT(status != NS_ERROR_TRACKING_URI,
|
||||
"NS_ERROR_TRACKING_URI needs to be handled by "
|
||||
"CancelForTrackingProtection()");
|
||||
#ifdef DEBUG
|
||||
if (UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(status)) {
|
||||
MOZ_CRASH_UNSAFE_PRINTF(
|
||||
"Blocking classifier error %" PRIx32
|
||||
" need to be handled by CancelForTrackingProtection()",
|
||||
static_cast<uint32_t>(status));
|
||||
}
|
||||
#endif
|
||||
|
||||
LOG(("nsHttpChannel::Cancel [this=%p status=%" PRIx32 "]\n", this,
|
||||
static_cast<uint32_t>(status)));
|
||||
|
@ -6088,7 +6094,7 @@ void nsHttpChannel::ContinueCancelledByTrackingProtection() {
|
|||
nsresult nsHttpChannel::CancelInternal(nsresult status) {
|
||||
bool trackingProtectionCancellationPending =
|
||||
!!mTrackingProtectionCancellationPending;
|
||||
if (status == NS_ERROR_TRACKING_URI) {
|
||||
if (UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(status)) {
|
||||
mTrackingProtectionCancellationPending = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "mozilla/AntiTrackingCommon.h"
|
||||
#include "mozilla/BasePrincipal.h"
|
||||
#include "mozilla/net/UrlClassifierFeatureFactory.h"
|
||||
#include "mozilla/StaticPrefs.h"
|
||||
#include "mozIThirdPartyUtil.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
@ -224,7 +225,7 @@ LazyLogModule UrlClassifierCommon::sLog("nsChannelClassifier");
|
|||
NS_ENSURE_TRUE(doc, NS_OK);
|
||||
|
||||
unsigned state;
|
||||
if (aErrorCode == NS_ERROR_TRACKING_URI) {
|
||||
if (UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(aErrorCode)) {
|
||||
state = nsIWebProgressListener::STATE_BLOCKED_TRACKING_CONTENT;
|
||||
} else {
|
||||
state = nsIWebProgressListener::STATE_BLOCKED_UNSAFE_CONTENT;
|
||||
|
@ -237,12 +238,16 @@ LazyLogModule UrlClassifierCommon::sLog("nsChannelClassifier");
|
|||
channel->GetURI(getter_AddRefs(uri));
|
||||
NS_ConvertUTF8toUTF16 spec(uri->GetSpecOrDefault());
|
||||
const char16_t* params[] = {spec.get()};
|
||||
const char* message = (aErrorCode == NS_ERROR_TRACKING_URI)
|
||||
? "TrackerUriBlocked"
|
||||
: "UnsafeUriBlocked";
|
||||
nsCString category = (aErrorCode == NS_ERROR_TRACKING_URI)
|
||||
? NS_LITERAL_CSTRING("Tracking Protection")
|
||||
: NS_LITERAL_CSTRING("Safe Browsing");
|
||||
const char* message;
|
||||
nsCString category;
|
||||
|
||||
if (UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(aErrorCode)) {
|
||||
message = UrlClassifierFeatureFactory::
|
||||
ClassifierBlockingErrorCodeToConsoleMessage(aErrorCode, category);
|
||||
} else {
|
||||
message = "UnsafeUriBlocked";
|
||||
category = NS_LITERAL_CSTRING("Safe Browsing");
|
||||
}
|
||||
|
||||
nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, category, doc,
|
||||
nsContentUtils::eNECKO_PROPERTIES, message,
|
||||
|
|
|
@ -205,5 +205,46 @@ UrlClassifierFeatureFactory::CreateFeatureWithTables(
|
|||
return feature.forget();
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
struct BlockingErrorCode {
|
||||
nsresult mErrorCode;
|
||||
const char* mConsoleMessage;
|
||||
nsCString mConsoleCategory;
|
||||
};
|
||||
|
||||
static const BlockingErrorCode sBlockingErrorCodes[] = {
|
||||
{NS_ERROR_TRACKING_URI, "TrackerUriBlocked",
|
||||
NS_LITERAL_CSTRING("Tracking Protection")},
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
/* static */ bool UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(
|
||||
nsresult aError) {
|
||||
// In theory we can iterate through the features, but at the moment, we can
|
||||
// just have a simple check here.
|
||||
for (const auto& blockingErrorCode : sBlockingErrorCodes) {
|
||||
if (aError == blockingErrorCode.mErrorCode) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* static */ const char*
|
||||
UrlClassifierFeatureFactory::ClassifierBlockingErrorCodeToConsoleMessage(
|
||||
nsresult aError, nsACString& aCategory) {
|
||||
for (const auto& blockingErrorCode : sBlockingErrorCodes) {
|
||||
if (aError == blockingErrorCode.mErrorCode) {
|
||||
aCategory = blockingErrorCode.mConsoleCategory;
|
||||
return blockingErrorCode.mConsoleMessage;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -37,6 +37,14 @@ class UrlClassifierFeatureFactory final {
|
|||
static already_AddRefed<nsIUrlClassifierFeature> CreateFeatureWithTables(
|
||||
const nsACString& aName, const nsTArray<nsCString>& aBlacklistTables,
|
||||
const nsTArray<nsCString>& aWhitelistTables);
|
||||
|
||||
// Returns true if this error is known as one of the blocking error codes.
|
||||
static bool IsClassifierBlockingErrorCode(nsresult aError);
|
||||
|
||||
// This can be called only if IsClassifierBlockingErrorCode(aError) returns
|
||||
// true.
|
||||
static const char* ClassifierBlockingErrorCodeToConsoleMessage(
|
||||
nsresult aError, nsACString& aCategory);
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/net/UrlClassifierCommon.h"
|
||||
#include "mozilla/net/UrlClassifierFeatureFactory.h"
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/Services.h"
|
||||
|
||||
|
@ -284,7 +285,8 @@ void nsChannelClassifier::MarkEntryClassified(nsresult status) {
|
|||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
|
||||
// Don't cache tracking classifications because we support allowlisting.
|
||||
if (status == NS_ERROR_TRACKING_URI || mIsAllowListed) {
|
||||
if (UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(status) ||
|
||||
mIsAllowListed) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -389,7 +391,8 @@ nsChannelClassifier::OnClassifyComplete(nsresult aErrorCode,
|
|||
const nsACString& aFullHash) {
|
||||
// Should only be called in the parent process.
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
MOZ_ASSERT(aErrorCode != NS_ERROR_TRACKING_URI);
|
||||
MOZ_ASSERT(
|
||||
!UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(aErrorCode));
|
||||
|
||||
if (mSuspendedChannel) {
|
||||
nsAutoCString errorName;
|
||||
|
|
|
@ -257,7 +257,7 @@ var State = {
|
|||
Cc["@mozilla.org/url-classifier/dbservice;1"].getService(Ci.nsIURIClassifier);
|
||||
classifier.classify(principal, null, true,
|
||||
(aErrorCode, aList, aProvider, aFullHash) => {
|
||||
this._trackingState.set(host, aErrorCode == Cr.NS_ERROR_TRACKING_URI);
|
||||
this._trackingState.set(host, ChromeUtils.IsClassifierBlockingErrorCode(aErrorCode));
|
||||
});
|
||||
}
|
||||
return this._trackingState.get(host);
|
||||
|
|
|
@ -80,7 +80,7 @@ add_task(async function() {
|
|||
{ expected: 3,
|
||||
},
|
||||
async function(obj) {
|
||||
is(content.document.blockedTrackingNodeCount, obj.expected, "Expected tracking nodes found");
|
||||
is(content.document.blockedNodeByClassifierCount, obj.expected, "Expected tracking nodes found");
|
||||
});
|
||||
|
||||
info("Removing the tab");
|
||||
|
|
|
@ -75,7 +75,7 @@ add_task(async function() {
|
|||
{ expected: gExpectedResourcesSeen,
|
||||
},
|
||||
async function(obj) {
|
||||
is(content.document.blockedTrackingNodeCount, obj.expected, "Expected tracking nodes found");
|
||||
is(content.document.blockedNodeByClassifierCount, obj.expected, "Expected tracking nodes found");
|
||||
});
|
||||
|
||||
info("Removing the tab");
|
||||
|
|
|
@ -27,7 +27,7 @@ function checkLoads() {
|
|||
window.parent.is(mediaItem1, "loaded", "Should not block tracking video");
|
||||
window.parent.is(xhrItem, "loaded", "Should not block tracking XHR");
|
||||
window.parent.is(fetchItem, "loaded", "Should not block fetches from tracking domains");
|
||||
window.parent.is(window.document.blockedTrackingNodeCount, 0,
|
||||
window.parent.is(window.document.blockedNodeByClassifierCount, 0,
|
||||
"No elements should be blocked");
|
||||
|
||||
// End (parent) test.
|
||||
|
|
|
@ -54,20 +54,20 @@ function checkLoads() {
|
|||
window.parent.isnot(
|
||||
style.visibility, "hidden", "Should not load tracking css");
|
||||
|
||||
window.parent.is(window.document.blockedTrackingNodeCount, badids.length,
|
||||
window.parent.is(window.document.blockedNodeByClassifierCount, badids.length,
|
||||
"Should identify all tracking elements");
|
||||
|
||||
var blockedTrackingNodes = window.document.blockedTrackingNodes;
|
||||
var blockedNodes = window.document.blockedNodesByClassifier;
|
||||
|
||||
// Make sure that every node in blockedTrackingNodes exists in the tree
|
||||
// Make sure that every node in blockedNodes exists in the tree
|
||||
// (that may not always be the case but do not expect any nodes to disappear
|
||||
// from the tree here)
|
||||
var allNodeMatch = true;
|
||||
for (let i = 0; i < blockedTrackingNodes.length; i++) {
|
||||
for (let i = 0; i < blockedNodes.length; i++) {
|
||||
let nodeMatch = false;
|
||||
for (let j = 0; j < badids.length && !nodeMatch; j++) {
|
||||
nodeMatch = nodeMatch ||
|
||||
(blockedTrackingNodes[i] == document.getElementById(badids[j]));
|
||||
(blockedNodes[i] == document.getElementById(badids[j]));
|
||||
}
|
||||
|
||||
allNodeMatch = allNodeMatch && nodeMatch;
|
||||
|
@ -76,18 +76,18 @@ function checkLoads() {
|
|||
"All annotated nodes are expected in the tree");
|
||||
|
||||
// Make sure that every node with a badid (see badids) is found in the
|
||||
// blockedTrackingNodes. This tells us if we are neglecting to annotate
|
||||
// blockedNodes. This tells us if we are neglecting to annotate
|
||||
// some nodes
|
||||
allNodeMatch = true;
|
||||
for (let j = 0; j < badids.length; j++) {
|
||||
let nodeMatch = false;
|
||||
for (let i = 0; i < blockedTrackingNodes.length && !nodeMatch; i++) {
|
||||
for (let i = 0; i < blockedNodes.length && !nodeMatch; i++) {
|
||||
nodeMatch = nodeMatch ||
|
||||
(blockedTrackingNodes[i] == document.getElementById(badids[j]));
|
||||
(blockedNodes[i] == document.getElementById(badids[j]));
|
||||
}
|
||||
|
||||
if (!nodeMatch) {
|
||||
console.log(badids[j] + " was not found in blockedTrackingNodes");
|
||||
console.log(badids[j] + " was not found in blockedNodes");
|
||||
}
|
||||
allNodeMatch = allNodeMatch && nodeMatch;
|
||||
}
|
||||
|
|
|
@ -72,19 +72,19 @@ function checkLoads(aWindow, aBlocked) {
|
|||
var style = win.document.defaultView.getComputedStyle(elt);
|
||||
isnot(style.visibility, aBlocked ? "hidden" : "", "Should not load tracking css");
|
||||
|
||||
is(win.document.blockedTrackingNodeCount, aBlocked ? badids.length : 0, "Should identify all tracking elements");
|
||||
is(win.document.blockedNodeByClassifierCount, aBlocked ? badids.length : 0, "Should identify all tracking elements");
|
||||
|
||||
var blockedTrackingNodes = win.document.blockedTrackingNodes;
|
||||
var blockedNodes = win.document.blockedNodesByClassifier;
|
||||
|
||||
// Make sure that every node in blockedTrackingNodes exists in the tree
|
||||
// Make sure that every node in blockedNodes exists in the tree
|
||||
// (that may not always be the case but do not expect any nodes to disappear
|
||||
// from the tree here)
|
||||
var allNodeMatch = true;
|
||||
for (let i = 0; i < blockedTrackingNodes.length; i++) {
|
||||
for (let i = 0; i < blockedNodes.length; i++) {
|
||||
let nodeMatch = false;
|
||||
for (let j = 0; j < badids.length && !nodeMatch; j++) {
|
||||
nodeMatch = nodeMatch ||
|
||||
(blockedTrackingNodes[i] == win.document.getElementById(badids[j]));
|
||||
(blockedNodes[i] == win.document.getElementById(badids[j]));
|
||||
}
|
||||
|
||||
allNodeMatch = allNodeMatch && nodeMatch;
|
||||
|
@ -92,14 +92,14 @@ function checkLoads(aWindow, aBlocked) {
|
|||
is(allNodeMatch, true, "All annotated nodes are expected in the tree");
|
||||
|
||||
// Make sure that every node with a badid (see badids) is found in the
|
||||
// blockedTrackingNodes. This tells us if we are neglecting to annotate
|
||||
// blockedNodes. This tells us if we are neglecting to annotate
|
||||
// some nodes
|
||||
allNodeMatch = true;
|
||||
for (let j = 0; j < badids.length; j++) {
|
||||
let nodeMatch = false;
|
||||
for (let i = 0; i < blockedTrackingNodes.length && !nodeMatch; i++) {
|
||||
for (let i = 0; i < blockedNodes.length && !nodeMatch; i++) {
|
||||
nodeMatch = nodeMatch ||
|
||||
(blockedTrackingNodes[i] == win.document.getElementById(badids[j]));
|
||||
(blockedNodes[i] == win.document.getElementById(badids[j]));
|
||||
}
|
||||
|
||||
allNodeMatch = allNodeMatch && nodeMatch;
|
||||
|
|
|
@ -61,7 +61,7 @@ function checkLoads(aWindow, aWhitelisted, tpEnabled) {
|
|||
var win = aWindow.content;
|
||||
if (!tpEnabled) {
|
||||
is(win.document.getElementById("badscript").dataset.touched, "yes", "Should load tracking javascript");
|
||||
is(win.document.blockedTrackingNodeCount, 0, "Should not identify any tracking elements");
|
||||
is(win.document.blockedNodeByClassifierCount, 0, "Should not identify any tracking elements");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -72,19 +72,19 @@ function checkLoads(aWindow, aWhitelisted, tpEnabled) {
|
|||
if (!aWhitelisted) {
|
||||
badids.push("goodscript");
|
||||
}
|
||||
is(win.document.blockedTrackingNodeCount, badids.length, "Should identify all tracking elements");
|
||||
is(win.document.blockedNodeByClassifierCount, badids.length, "Should identify all tracking elements");
|
||||
|
||||
var blockedTrackingNodes = win.document.blockedTrackingNodes;
|
||||
var blockedNodes = win.document.blockedNodesByClassifier;
|
||||
|
||||
// Make sure that every node in blockedTrackingNodes exists in the tree
|
||||
// Make sure that every node in blockedNodes exists in the tree
|
||||
// (that may not always be the case but do not expect any nodes to disappear
|
||||
// from the tree here)
|
||||
var allNodeMatch = true;
|
||||
for (let i = 0; i < blockedTrackingNodes.length; i++) {
|
||||
for (let i = 0; i < blockedNodes.length; i++) {
|
||||
let nodeMatch = false;
|
||||
for (let j = 0; j < badids.length && !nodeMatch; j++) {
|
||||
nodeMatch = nodeMatch ||
|
||||
(blockedTrackingNodes[i] == win.document.getElementById(badids[j]));
|
||||
(blockedNodes[i] == win.document.getElementById(badids[j]));
|
||||
}
|
||||
|
||||
allNodeMatch = allNodeMatch && nodeMatch;
|
||||
|
@ -92,14 +92,14 @@ function checkLoads(aWindow, aWhitelisted, tpEnabled) {
|
|||
is(allNodeMatch, true, "All annotated nodes are expected in the tree");
|
||||
|
||||
// Make sure that every node with a badid (see badids) is found in the
|
||||
// blockedTrackingNodes. This tells us if we are neglecting to annotate
|
||||
// blockedNodes. This tells us if we are neglecting to annotate
|
||||
// some nodes
|
||||
allNodeMatch = true;
|
||||
for (let j = 0; j < badids.length; j++) {
|
||||
let nodeMatch = false;
|
||||
for (let i = 0; i < blockedTrackingNodes.length && !nodeMatch; i++) {
|
||||
for (let i = 0; i < blockedNodes.length && !nodeMatch; i++) {
|
||||
nodeMatch = nodeMatch ||
|
||||
(blockedTrackingNodes[i] == win.document.getElementById(badids[j]));
|
||||
(blockedNodes[i] == win.document.getElementById(badids[j]));
|
||||
}
|
||||
|
||||
allNodeMatch = allNodeMatch && nodeMatch;
|
||||
|
|
Загрузка…
Ссылка в новой задаче