/* -*- 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/. */
/* static */ bool UrlClassifierCommon::AddonMayLoad(nsIChannel* aChannel, nsIURI* aURI) {
nsCOMPtr<nsILoadInfo> channelLoadInfo = aChannel->LoadInfo(); // loadingPrincipal is used here to ensure we are loading into an // addon principal. This allows an addon, with explicit permission, to // call out to API endpoints that may otherwise get blocked.
nsIPrincipal* loadingPrincipal = channelLoadInfo->GetLoadingPrincipal(); if (!loadingPrincipal) { returnfalse;
}
auto policyType = loadInfo->GetExternalContentPolicyType(); if (policyType == ExtContentPolicy::TYPE_DOCUMENT) {
UC_LOG(
("UrlClassifierCommon::ShouldEnableProtectionForChannel - " "skipping top-level load for channel %p",
aChannel)); returnfalse;
}
// Tracking protection will be enabled so return without updating // the security state. If any channels are subsequently cancelled // (page elements blocked) the state will be then updated.
// Can be called in EITHER the parent or child process.
nsresult rv;
nsCOMPtr<nsIClassifiedChannel> classifiedChannel =
do_QueryInterface(aChannel, &rv);
NS_ENSURE_SUCCESS(rv, rv);
if (classifiedChannel) {
classifiedChannel->SetMatchedTrackingInfo(aLists, aFullHashes);
}
nsCOMPtr<nsIParentChannel> parentChannel;
NS_QueryNotificationCallbacks(aChannel, parentChannel); if (parentChannel) { // This channel is a parent-process proxy for a child process request. // Tell the child process channel to do this as well. // TODO: We can remove the code sending the IPC to content to update // tracking info once we move the ContentBlockingLog into the parent. // This would be done in Bug 1599046.
nsAutoCString strLists, strHashes;
TablesToString(aLists, strLists);
TablesToString(aFullHashes, strHashes);
switch (aErrorCode) { case NS_ERROR_MALWARE_URI:
NS_SetRequestBlockingReason(
channel, nsILoadInfo::BLOCKING_REASON_CLASSIFY_MALWARE_URI); break; case NS_ERROR_PHISHING_URI:
NS_SetRequestBlockingReason(
channel, nsILoadInfo::BLOCKING_REASON_CLASSIFY_PHISHING_URI); break; case NS_ERROR_UNWANTED_URI:
NS_SetRequestBlockingReason(
channel, nsILoadInfo::BLOCKING_REASON_CLASSIFY_UNWANTED_URI); break; case NS_ERROR_TRACKING_URI:
NS_SetRequestBlockingReason(
channel, nsILoadInfo::BLOCKING_REASON_CLASSIFY_TRACKING_URI); break; case NS_ERROR_BLOCKED_URI:
NS_SetRequestBlockingReason(
channel, nsILoadInfo::BLOCKING_REASON_CLASSIFY_BLOCKED_URI); break; case NS_ERROR_HARMFUL_URI:
NS_SetRequestBlockingReason(
channel, nsILoadInfo::BLOCKING_REASON_CLASSIFY_HARMFUL_URI); break; case NS_ERROR_CRYPTOMINING_URI:
NS_SetRequestBlockingReason(
channel, nsILoadInfo::BLOCKING_REASON_CLASSIFY_CRYPTOMINING_URI); break; case NS_ERROR_FINGERPRINTING_URI:
NS_SetRequestBlockingReason(
channel, nsILoadInfo::BLOCKING_REASON_CLASSIFY_FINGERPRINTING_URI); break; case NS_ERROR_SOCIALTRACKING_URI:
NS_SetRequestBlockingReason(
channel, nsILoadInfo::BLOCKING_REASON_CLASSIFY_SOCIALTRACKING_URI); break; case NS_ERROR_EMAILTRACKING_URI:
NS_SetRequestBlockingReason(
channel, nsILoadInfo::BLOCKING_REASON_CLASSIFY_EMAILTRACKING_URI); break; default:
MOZ_CRASH( "Missing nsILoadInfo::BLOCKING_REASON* for the classification error"); break;
}
// Can be called in EITHER the parent or child process.
nsresult rv;
nsCOMPtr<nsIClassifiedChannel> classifiedChannel =
do_QueryInterface(channel, &rv);
NS_ENSURE_SUCCESS(rv, rv);
if (classifiedChannel) {
classifiedChannel->SetMatchedInfo(aList, aProvider, aFullHash);
}
if (XRE_IsParentProcess()) {
nsCOMPtr<nsIParentChannel> parentChannel;
NS_QueryNotificationCallbacks(channel, parentChannel); if (parentChannel) { // This channel is a parent-process proxy for a child process request. // Tell the child process channel to do this as well. // TODO: We can remove the code sending the IPC to content to update // matched info once we move the ContentBlockingLog into the parent. // This would be done in Bug 1601063.
parentChannel->SetClassifierMatchedInfo(aList, aProvider, aFullHash);
}
unsigned state =
UrlClassifierFeatureFactory::GetClassifierBlockingEventCode(aErrorCode); if (!state) {
state = nsIWebProgressListener::STATE_BLOCKED_UNSAFE_CONTENT;
}
ContentBlockingNotifier::OnEvent(channel, state);
return NS_OK;
}
// TODO: ReportToConsole is called in the child process, // If nsContentUtils::ReportToConsole is not fission compatiable(cannot report // to correct top-level window), we need to do this in the parent process // instead (find the top-level window in the parent and send an IPC to child // processes to report console).
nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil;
thirdPartyUtil = mozilla::components::ThirdPartyUtil::Service(); if (NS_WARN_IF(!thirdPartyUtil)) { return NS_OK;
}
// Log a warning to the web console.
nsCOMPtr<nsIURI> uri;
channel->GetURI(getter_AddRefs(uri));
AutoTArray<nsString, 1> params;
CopyUTF8toUTF16(uri->GetSpecOrDefault(), *params.AppendElement()); constchar* message;
nsCString category;
nsCOMPtr<nsIURI> topWinURI;
rv =
UrlClassifierCommon::GetTopWindowURI(aChannel, getter_AddRefs(topWinURI)); if (NS_FAILED(rv) || !topWinURI) { // SharedWorker and ServiceWorker don't have an associated window, use // client's URI instead.
nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
MOZ_ASSERT(loadInfo);
Maybe<dom::ClientInfo> clientInfo = loadInfo->GetClientInfo(); if (clientInfo.isSome()) { if ((clientInfo->Type() == dom::ClientType::Sharedworker) ||
(clientInfo->Type() == dom::ClientType::Serviceworker)) {
UC_LOG(
("UrlClassifierCommon::CreatePairwiseEntityListURI - " "channel %p initiated by worker, get uri from client",
aChannel));
auto clientPrincipalOrErr = clientInfo->GetPrincipal(); if (clientPrincipalOrErr.isOk()) {
nsCOMPtr<nsIPrincipal> principal = clientPrincipalOrErr.unwrap(); if (principal) { auto* basePrin = BasePrincipal::Cast(principal);
rv = basePrin->GetURI(getter_AddRefs(topWinURI));
Unused << NS_WARN_IF(NS_FAILED(rv));
}
}
}
}
if (!topWinURI) {
UC_LOG(
("UrlClassifierCommon::CreatePairwiseEntityListURI - " "no top-level window associated with channel %p, " "get uri from loading principal",
aChannel));
nsCOMPtr<nsIPrincipal> principal = loadInfo->GetLoadingPrincipal(); if (principal) { auto* basePrin = BasePrincipal::Cast(principal);
rv = basePrin->GetURI(getter_AddRefs(topWinURI));
Unused << NS_WARN_IF(NS_FAILED(rv));
}
}
}
if (!topWinURI) {
UC_LOG(
("UrlClassifierCommon::CreatePairwiseEntityListURI - " "fail to get top-level window uri for channel %p",
aChannel));
// Return success because we want to continue to look up even without // whitelist. return NS_OK;
}
// Craft a entitylist URL like "toplevel.page/?resource=third.party.domain"
nsAutoCString pageHostname, resourceDomain;
rv = topWinURI->GetHost(pageHostname); if (NS_FAILED(rv)) { // When the top-level page doesn't support GetHost, for example, about:home, // we don't return an error here; instead, we return success to make sure // that the lookup process calling this API continues to run. if (UC_LOG_ENABLED()) {
nsCString topWinSpec =
topWinURI ? topWinURI->GetSpecOrDefault() : "(null)"_ns;
topWinSpec.Truncate(
std::min(topWinSpec.Length(), UrlClassifierCommon::sMaxSpecLength));
UC_LOG(
("UrlClassifierCommon::CreatePairwiseEntityListURI - " "cannot get host from the top-level uri %s of channel %p",
topWinSpec.get(), aChannel));
} return NS_OK;
}
rv = chanPrincipal->GetBaseDomain(resourceDomain);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoCString entitylistEntry = "http://"_ns + pageHostname + "/?resource="_ns + resourceDomain;
UC_LOG(
("UrlClassifierCommon::CreatePairwiseEntityListURI - looking for %s in " "the entitylist on channel %p",
entitylistEntry.get(), aChannel));
// Requests not allowed to be tailed are usually those with higher // prioritization. That overweights being a tracker: don't throttle // them when not in background. if (!(cosFlags & nsIClassOfService::TailForbidden)) {
cos->AddClassFlags(nsIClassOfService::Throttleable);
}
} else { // Yes, we even don't want to evaluate the isBlockingResource when tailing // is off see bug 1395525.
nsCOMPtr<nsIParentChannel> parentChannel;
NS_QueryNotificationCallbacks(aChannel, parentChannel); if (parentChannel) { // This channel is a parent-process proxy for a child process // request. We should notify the child process as well.
parentChannel->NotifyClassificationFlags(aClassificationFlags,
aIsThirdParty);
}
// We consider valid tracking flags (based on the current strict vs basic list // prefs) and cryptomining (which is not considered as tracking). bool validClassificationFlags =
IsTrackingClassificationFlag(aClassificationFlags,
NS_UsePrivateBrowsing(aChannel)) ||
IsCryptominingClassificationFlag(aClassificationFlags,
NS_UsePrivateBrowsing(aChannel));
if (validClassificationFlags && isThirdPartyWithTopLevelWinURI) {
ContentBlockingNotifier::OnEvent(aChannel, aLoadingState);
}
if (isThirdPartyWithTopLevelWinURI &&
StaticPrefs::privacy_trackingprotection_lower_network_priority()) {
LowerPriorityHelper(aChannel);
}
}
if (isLevel2ListEnabled &&
(aFlag & nsIClassifiedChannel::ClassificationFlags::
CLASSIFIED_CRYPTOMINING_CONTENT)) { returntrue;
}
returnfalse;
}
void UrlClassifierCommon::TablesToString(const nsTArray<nsCString>& aList,
nsACString& aString) { // Truncate and append rather than assigning because that's more efficient if // aString is an nsAutoCString.
aString.Truncate();
StringJoinAppend(aString, ","_ns, aList);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.