Backed out changeset 2450366cf7ca (bug 1891629) for causing win msix mochitest failures
[gecko.git] / netwerk / url-classifier / UrlClassifierCommon.cpp
blob21589cef94670f5175fc9ff47177e53f67195330
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozilla/net/UrlClassifierCommon.h"
9 #include "mozilla/AntiTrackingUtils.h"
10 #include "mozilla/BasePrincipal.h"
11 #include "mozilla/Components.h"
12 #include "mozilla/ContentBlockingAllowList.h"
13 #include "mozilla/ContentBlockingNotifier.h"
14 #include "mozilla/dom/WindowGlobalParent.h"
15 #include "mozilla/net/HttpBaseChannel.h"
16 #include "mozilla/net/UrlClassifierFeatureFactory.h"
17 #include "mozilla/StaticPrefs_network.h"
18 #include "mozilla/StaticPrefs_privacy.h"
19 #include "mozilla/StaticPrefs_channelclassifier.h"
20 #include "mozilla/StaticPrefs_security.h"
21 #include "mozIThirdPartyUtil.h"
22 #include "nsContentUtils.h"
23 #include "nsIChannel.h"
24 #include "nsIClassifiedChannel.h"
25 #include "mozilla/dom/Document.h"
26 #include "nsIDocShell.h"
27 #include "nsIHttpChannel.h"
28 #include "nsIHttpChannelInternal.h"
29 #include "nsIParentChannel.h"
30 #include "nsIScriptError.h"
31 #include "nsIWebProgressListener.h"
32 #include "nsNetUtil.h"
33 #include "nsQueryObject.h"
34 #include "nsReadableUtils.h"
36 namespace mozilla {
37 namespace net {
39 const nsCString::size_type UrlClassifierCommon::sMaxSpecLength = 128;
41 // MOZ_LOG=nsChannelClassifier:5
42 LazyLogModule UrlClassifierCommon::sLog("nsChannelClassifier");
43 LazyLogModule UrlClassifierCommon::sLogLeak("nsChannelClassifierLeak");
45 /* static */
46 bool UrlClassifierCommon::AddonMayLoad(nsIChannel* aChannel, nsIURI* aURI) {
47 nsCOMPtr<nsILoadInfo> channelLoadInfo = aChannel->LoadInfo();
48 // loadingPrincipal is used here to ensure we are loading into an
49 // addon principal. This allows an addon, with explicit permission, to
50 // call out to API endpoints that may otherwise get blocked.
51 nsIPrincipal* loadingPrincipal = channelLoadInfo->GetLoadingPrincipal();
52 if (!loadingPrincipal) {
53 return false;
56 return BasePrincipal::Cast(loadingPrincipal)->AddonAllowsLoad(aURI, true);
59 /* static */
60 bool UrlClassifierCommon::ShouldEnableProtectionForChannel(
61 nsIChannel* aChannel) {
62 MOZ_ASSERT(aChannel);
64 nsCOMPtr<nsIURI> chanURI;
65 nsresult rv = aChannel->GetURI(getter_AddRefs(chanURI));
66 if (NS_WARN_IF(NS_FAILED(rv))) {
67 return false;
70 if (UrlClassifierCommon::AddonMayLoad(aChannel, chanURI)) {
71 return false;
74 nsCOMPtr<nsIURI> topWinURI;
75 nsCOMPtr<nsIHttpChannelInternal> channel = do_QueryInterface(aChannel);
76 if (NS_WARN_IF(!channel)) {
77 return false;
80 nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
81 MOZ_ASSERT(loadInfo);
83 auto policyType = loadInfo->GetExternalContentPolicyType();
84 if (policyType == ExtContentPolicy::TYPE_DOCUMENT) {
85 UC_LOG(
86 ("UrlClassifierCommon::ShouldEnableProtectionForChannel - "
87 "skipping top-level load for channel %p",
88 aChannel));
89 return false;
92 // Tracking protection will be enabled so return without updating
93 // the security state. If any channels are subsequently cancelled
94 // (page elements blocked) the state will be then updated.
96 return true;
99 /* static */
100 nsresult UrlClassifierCommon::SetTrackingInfo(
101 nsIChannel* aChannel, const nsTArray<nsCString>& aLists,
102 const nsTArray<nsCString>& aFullHashes) {
103 NS_ENSURE_ARG(!aLists.IsEmpty());
105 // Can be called in EITHER the parent or child process.
106 nsresult rv;
107 nsCOMPtr<nsIClassifiedChannel> classifiedChannel =
108 do_QueryInterface(aChannel, &rv);
109 NS_ENSURE_SUCCESS(rv, rv);
111 if (classifiedChannel) {
112 classifiedChannel->SetMatchedTrackingInfo(aLists, aFullHashes);
115 nsCOMPtr<nsIParentChannel> parentChannel;
116 NS_QueryNotificationCallbacks(aChannel, parentChannel);
117 if (parentChannel) {
118 // This channel is a parent-process proxy for a child process request.
119 // Tell the child process channel to do this as well.
120 // TODO: We can remove the code sending the IPC to content to update
121 // tracking info once we move the ContentBlockingLog into the parent.
122 // This would be done in Bug 1599046.
123 nsAutoCString strLists, strHashes;
124 TablesToString(aLists, strLists);
125 TablesToString(aFullHashes, strHashes);
127 parentChannel->SetClassifierMatchedTrackingInfo(strLists, strHashes);
130 return NS_OK;
133 /* static */
134 nsresult UrlClassifierCommon::SetBlockedContent(nsIChannel* channel,
135 nsresult aErrorCode,
136 const nsACString& aList,
137 const nsACString& aProvider,
138 const nsACString& aFullHash) {
139 NS_ENSURE_ARG(!aList.IsEmpty());
141 switch (aErrorCode) {
142 case NS_ERROR_MALWARE_URI:
143 NS_SetRequestBlockingReason(
144 channel, nsILoadInfo::BLOCKING_REASON_CLASSIFY_MALWARE_URI);
145 break;
146 case NS_ERROR_PHISHING_URI:
147 NS_SetRequestBlockingReason(
148 channel, nsILoadInfo::BLOCKING_REASON_CLASSIFY_PHISHING_URI);
149 break;
150 case NS_ERROR_UNWANTED_URI:
151 NS_SetRequestBlockingReason(
152 channel, nsILoadInfo::BLOCKING_REASON_CLASSIFY_UNWANTED_URI);
153 break;
154 case NS_ERROR_TRACKING_URI:
155 NS_SetRequestBlockingReason(
156 channel, nsILoadInfo::BLOCKING_REASON_CLASSIFY_TRACKING_URI);
157 break;
158 case NS_ERROR_BLOCKED_URI:
159 NS_SetRequestBlockingReason(
160 channel, nsILoadInfo::BLOCKING_REASON_CLASSIFY_BLOCKED_URI);
161 break;
162 case NS_ERROR_HARMFUL_URI:
163 NS_SetRequestBlockingReason(
164 channel, nsILoadInfo::BLOCKING_REASON_CLASSIFY_HARMFUL_URI);
165 break;
166 case NS_ERROR_CRYPTOMINING_URI:
167 NS_SetRequestBlockingReason(
168 channel, nsILoadInfo::BLOCKING_REASON_CLASSIFY_CRYPTOMINING_URI);
169 break;
170 case NS_ERROR_FINGERPRINTING_URI:
171 NS_SetRequestBlockingReason(
172 channel, nsILoadInfo::BLOCKING_REASON_CLASSIFY_FINGERPRINTING_URI);
173 break;
174 case NS_ERROR_SOCIALTRACKING_URI:
175 NS_SetRequestBlockingReason(
176 channel, nsILoadInfo::BLOCKING_REASON_CLASSIFY_SOCIALTRACKING_URI);
177 break;
178 case NS_ERROR_EMAILTRACKING_URI:
179 NS_SetRequestBlockingReason(
180 channel, nsILoadInfo::BLOCKING_REASON_CLASSIFY_EMAILTRACKING_URI);
181 break;
182 default:
183 MOZ_CRASH(
184 "Missing nsILoadInfo::BLOCKING_REASON* for the classification error");
185 break;
188 // Can be called in EITHER the parent or child process.
189 nsresult rv;
190 nsCOMPtr<nsIClassifiedChannel> classifiedChannel =
191 do_QueryInterface(channel, &rv);
192 NS_ENSURE_SUCCESS(rv, rv);
194 if (classifiedChannel) {
195 classifiedChannel->SetMatchedInfo(aList, aProvider, aFullHash);
198 if (XRE_IsParentProcess()) {
199 nsCOMPtr<nsIParentChannel> parentChannel;
200 NS_QueryNotificationCallbacks(channel, parentChannel);
201 if (parentChannel) {
202 // This channel is a parent-process proxy for a child process request.
203 // Tell the child process channel to do this as well.
204 // TODO: We can remove the code sending the IPC to content to update
205 // matched info once we move the ContentBlockingLog into the parent.
206 // This would be done in Bug 1601063.
207 parentChannel->SetClassifierMatchedInfo(aList, aProvider, aFullHash);
210 unsigned state =
211 UrlClassifierFeatureFactory::GetClassifierBlockingEventCode(aErrorCode);
212 if (!state) {
213 state = nsIWebProgressListener::STATE_BLOCKED_UNSAFE_CONTENT;
215 ContentBlockingNotifier::OnEvent(channel, state);
217 return NS_OK;
220 // TODO: ReportToConsole is called in the child process,
221 // If nsContentUtils::ReportToConsole is not fission compatiable(cannot report
222 // to correct top-level window), we need to do this in the parent process
223 // instead (find the top-level window in the parent and send an IPC to child
224 // processes to report console).
225 nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil =
226 components::ThirdPartyUtil::Service();
227 if (NS_WARN_IF(!thirdPartyUtil)) {
228 return NS_OK;
231 nsCOMPtr<nsIURI> uriBeingLoaded =
232 AntiTrackingUtils::MaybeGetDocumentURIBeingLoaded(channel);
233 nsCOMPtr<mozIDOMWindowProxy> win;
234 rv = thirdPartyUtil->GetTopWindowForChannel(channel, uriBeingLoaded,
235 getter_AddRefs(win));
236 NS_ENSURE_SUCCESS(rv, NS_OK);
237 auto* pwin = nsPIDOMWindowOuter::From(win);
238 nsCOMPtr<nsIDocShell> docShell = pwin->GetDocShell();
239 if (!docShell) {
240 return NS_OK;
242 RefPtr<dom::Document> doc = docShell->GetDocument();
243 NS_ENSURE_TRUE(doc, NS_OK);
245 // Log a warning to the web console.
246 nsCOMPtr<nsIURI> uri;
247 channel->GetURI(getter_AddRefs(uri));
248 AutoTArray<nsString, 1> params;
249 CopyUTF8toUTF16(uri->GetSpecOrDefault(), *params.AppendElement());
250 const char* message;
251 nsCString category;
253 if (UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(aErrorCode)) {
254 message = UrlClassifierFeatureFactory::
255 ClassifierBlockingErrorCodeToConsoleMessage(aErrorCode, category);
256 } else {
257 message = "UnsafeUriBlocked";
258 category = "Safe Browsing"_ns;
261 nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, category, doc,
262 nsContentUtils::eNECKO_PROPERTIES, message,
263 params);
265 return NS_OK;
268 /* static */
269 nsresult UrlClassifierCommon::GetTopWindowURI(nsIChannel* aChannel,
270 nsIURI** aURI) {
271 MOZ_ASSERT(XRE_IsParentProcess());
272 MOZ_ASSERT(aChannel);
274 nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
275 MOZ_ASSERT(loadInfo);
277 RefPtr<dom::BrowsingContext> browsingContext;
278 nsresult rv =
279 loadInfo->GetTargetBrowsingContext(getter_AddRefs(browsingContext));
280 if (NS_WARN_IF(NS_FAILED(rv)) || !browsingContext) {
281 return NS_ERROR_FAILURE;
284 dom::CanonicalBrowsingContext* top = browsingContext->Canonical()->Top();
285 dom::WindowGlobalParent* wgp = top->GetCurrentWindowGlobal();
286 if (!wgp) {
287 return NS_ERROR_FAILURE;
290 RefPtr<nsIURI> uri = wgp->GetDocumentURI();
291 if (!uri) {
292 return NS_ERROR_FAILURE;
295 uri.forget(aURI);
296 return NS_OK;
299 /* static */
300 nsresult UrlClassifierCommon::CreatePairwiseEntityListURI(nsIChannel* aChannel,
301 nsIURI** aURI) {
302 MOZ_ASSERT(aChannel);
303 MOZ_ASSERT(aURI);
305 nsresult rv;
306 nsCOMPtr<nsIHttpChannelInternal> chan = do_QueryInterface(aChannel, &rv);
307 NS_ENSURE_SUCCESS(rv, rv);
308 if (!chan) {
309 return NS_ERROR_FAILURE;
312 nsCOMPtr<nsIURI> topWinURI;
313 rv =
314 UrlClassifierCommon::GetTopWindowURI(aChannel, getter_AddRefs(topWinURI));
315 if (NS_FAILED(rv) || !topWinURI) {
316 // SharedWorker and ServiceWorker don't have an associated window, use
317 // client's URI instead.
318 nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
319 MOZ_ASSERT(loadInfo);
321 Maybe<dom::ClientInfo> clientInfo = loadInfo->GetClientInfo();
322 if (clientInfo.isSome()) {
323 if ((clientInfo->Type() == dom::ClientType::Sharedworker) ||
324 (clientInfo->Type() == dom::ClientType::Serviceworker)) {
325 UC_LOG(
326 ("UrlClassifierCommon::CreatePairwiseEntityListURI - "
327 "channel %p initiated by worker, get uri from client",
328 aChannel));
330 auto clientPrincipalOrErr = clientInfo->GetPrincipal();
331 if (clientPrincipalOrErr.isOk()) {
332 nsCOMPtr<nsIPrincipal> principal = clientPrincipalOrErr.unwrap();
333 if (principal) {
334 auto* basePrin = BasePrincipal::Cast(principal);
335 rv = basePrin->GetURI(getter_AddRefs(topWinURI));
336 Unused << NS_WARN_IF(NS_FAILED(rv));
342 if (!topWinURI) {
343 UC_LOG(
344 ("UrlClassifierCommon::CreatePairwiseEntityListURI - "
345 "no top-level window associated with channel %p, "
346 "get uri from loading principal",
347 aChannel));
349 nsCOMPtr<nsIPrincipal> principal = loadInfo->GetLoadingPrincipal();
350 if (principal) {
351 auto* basePrin = BasePrincipal::Cast(principal);
352 rv = basePrin->GetURI(getter_AddRefs(topWinURI));
353 Unused << NS_WARN_IF(NS_FAILED(rv));
358 if (!topWinURI) {
359 UC_LOG(
360 ("UrlClassifierCommon::CreatePairwiseEntityListURI - "
361 "fail to get top-level window uri for channel %p",
362 aChannel));
364 // Return success because we want to continue to look up even without
365 // whitelist.
366 return NS_OK;
369 nsCOMPtr<nsIScriptSecurityManager> securityManager =
370 do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
371 NS_ENSURE_SUCCESS(rv, rv);
372 nsCOMPtr<nsIPrincipal> chanPrincipal;
373 rv = securityManager->GetChannelURIPrincipal(aChannel,
374 getter_AddRefs(chanPrincipal));
375 NS_ENSURE_SUCCESS(rv, rv);
377 // Craft a entitylist URL like "toplevel.page/?resource=third.party.domain"
378 nsAutoCString pageHostname, resourceDomain;
379 rv = topWinURI->GetHost(pageHostname);
380 if (NS_FAILED(rv)) {
381 // When the top-level page doesn't support GetHost, for example, about:home,
382 // we don't return an error here; instead, we return success to make sure
383 // that the lookup process calling this API continues to run.
384 if (UC_LOG_ENABLED()) {
385 nsCString topWinSpec =
386 topWinURI ? topWinURI->GetSpecOrDefault() : "(null)"_ns;
387 topWinSpec.Truncate(
388 std::min(topWinSpec.Length(), UrlClassifierCommon::sMaxSpecLength));
389 UC_LOG(
390 ("UrlClassifierCommon::CreatePairwiseEntityListURI - "
391 "cannot get host from the top-level uri %s of channel %p",
392 topWinSpec.get(), aChannel));
394 return NS_OK;
397 rv = chanPrincipal->GetBaseDomain(resourceDomain);
398 NS_ENSURE_SUCCESS(rv, rv);
399 nsAutoCString entitylistEntry =
400 "http://"_ns + pageHostname + "/?resource="_ns + resourceDomain;
401 UC_LOG(
402 ("UrlClassifierCommon::CreatePairwiseEntityListURI - looking for %s in "
403 "the entitylist on channel %p",
404 entitylistEntry.get(), aChannel));
406 nsCOMPtr<nsIURI> entitylistURI;
407 rv = NS_NewURI(getter_AddRefs(entitylistURI), entitylistEntry);
408 if (NS_FAILED(rv)) {
409 return rv;
412 entitylistURI.forget(aURI);
413 return NS_OK;
416 namespace {
418 void LowerPriorityHelper(nsIChannel* aChannel) {
419 MOZ_ASSERT(aChannel);
421 bool isBlockingResource = false;
423 nsCOMPtr<nsIClassOfService> cos(do_QueryInterface(aChannel));
424 if (cos) {
425 if (StaticPrefs::network_http_tailing_enabled()) {
426 uint32_t cosFlags = 0;
427 cos->GetClassFlags(&cosFlags);
428 isBlockingResource =
429 cosFlags & (nsIClassOfService::UrgentStart |
430 nsIClassOfService::Leader | nsIClassOfService::Unblocked);
432 // Requests not allowed to be tailed are usually those with higher
433 // prioritization. That overweights being a tracker: don't throttle
434 // them when not in background.
435 if (!(cosFlags & nsIClassOfService::TailForbidden)) {
436 cos->AddClassFlags(nsIClassOfService::Throttleable);
438 } else {
439 // Yes, we even don't want to evaluate the isBlockingResource when tailing
440 // is off see bug 1395525.
442 cos->AddClassFlags(nsIClassOfService::Throttleable);
446 if (!isBlockingResource) {
447 nsCOMPtr<nsISupportsPriority> p = do_QueryInterface(aChannel);
448 if (p) {
449 UC_LOG(
450 ("UrlClassifierCommon::LowerPriorityHelper - "
451 "setting PRIORITY_LOWEST for channel %p",
452 aChannel));
453 p->SetPriority(nsISupportsPriority::PRIORITY_LOWEST);
458 } // namespace
460 // static
461 void UrlClassifierCommon::SetClassificationFlagsHelper(
462 nsIChannel* aChannel, uint32_t aClassificationFlags, bool aIsThirdParty) {
463 MOZ_ASSERT(aChannel);
465 nsCOMPtr<nsIParentChannel> parentChannel;
466 NS_QueryNotificationCallbacks(aChannel, parentChannel);
467 if (parentChannel) {
468 // This channel is a parent-process proxy for a child process
469 // request. We should notify the child process as well.
470 parentChannel->NotifyClassificationFlags(aClassificationFlags,
471 aIsThirdParty);
474 RefPtr<HttpBaseChannel> httpChannel = do_QueryObject(aChannel);
475 if (httpChannel) {
476 httpChannel->AddClassificationFlags(aClassificationFlags, aIsThirdParty);
480 // static
481 void UrlClassifierCommon::AnnotateChannel(nsIChannel* aChannel,
482 uint32_t aClassificationFlags,
483 uint32_t aLoadingState) {
484 MOZ_ASSERT(XRE_IsParentProcess());
485 MOZ_ASSERT(aChannel);
487 nsCOMPtr<nsIURI> chanURI;
488 nsresult rv = aChannel->GetURI(getter_AddRefs(chanURI));
489 if (NS_WARN_IF(NS_FAILED(rv))) {
490 return;
493 bool isThirdPartyWithTopLevelWinURI =
494 AntiTrackingUtils::IsThirdPartyChannel(aChannel);
496 SetClassificationFlagsHelper(aChannel, aClassificationFlags,
497 isThirdPartyWithTopLevelWinURI);
499 // We consider valid tracking flags (based on the current strict vs basic list
500 // prefs) and cryptomining (which is not considered as tracking).
501 bool validClassificationFlags =
502 IsTrackingClassificationFlag(aClassificationFlags,
503 NS_UsePrivateBrowsing(aChannel)) ||
504 IsCryptominingClassificationFlag(aClassificationFlags,
505 NS_UsePrivateBrowsing(aChannel));
507 if (validClassificationFlags && isThirdPartyWithTopLevelWinURI) {
508 ContentBlockingNotifier::OnEvent(aChannel, aLoadingState);
511 if (isThirdPartyWithTopLevelWinURI &&
512 StaticPrefs::privacy_trackingprotection_lower_network_priority()) {
513 LowerPriorityHelper(aChannel);
517 // static
518 bool UrlClassifierCommon::IsAllowListed(nsIChannel* aChannel) {
519 nsCOMPtr<nsIHttpChannelInternal> channel = do_QueryInterface(aChannel);
520 if (NS_WARN_IF(!channel)) {
521 return false;
524 nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
526 bool isAllowListed = false;
527 if (StaticPrefs::channelclassifier_allowlist_example()) {
528 UC_LOG(
529 ("UrlClassifierCommon::IsAllowListed - "
530 "check allowlisting test domain on channel %p",
531 aChannel));
533 nsCOMPtr<nsIIOService> ios = components::IO::Service();
534 if (NS_WARN_IF(!ios)) {
535 return false;
538 nsCOMPtr<nsIURI> uri;
539 nsresult rv = ios->NewURI("http://allowlisted.example.com"_ns, nullptr,
540 nullptr, getter_AddRefs(uri));
541 if (NS_WARN_IF(NS_FAILED(rv))) {
542 return false;
544 nsCOMPtr<nsIPrincipal> cbAllowListPrincipal =
545 BasePrincipal::CreateContentPrincipal(uri,
546 loadInfo->GetOriginAttributes());
548 rv = ContentBlockingAllowList::Check(
549 cbAllowListPrincipal, NS_UsePrivateBrowsing(aChannel), isAllowListed);
550 if (NS_WARN_IF(NS_FAILED(rv))) {
551 return false;
553 } else {
554 nsCOMPtr<nsICookieJarSettings> cookieJarSettings;
555 MOZ_ALWAYS_SUCCEEDS(
556 loadInfo->GetCookieJarSettings(getter_AddRefs(cookieJarSettings)));
557 isAllowListed = cookieJarSettings->GetIsOnContentBlockingAllowList();
560 if (isAllowListed) {
561 UC_LOG(("UrlClassifierCommon::IsAllowListed - user override on channel %p",
562 aChannel));
565 return isAllowListed;
568 // static
569 bool UrlClassifierCommon::IsTrackingClassificationFlag(uint32_t aFlag,
570 bool aIsPrivate) {
571 bool isLevel2ListEnabled =
572 aIsPrivate
573 ? StaticPrefs::privacy_annotate_channels_strict_list_pbmode_enabled()
574 : StaticPrefs::privacy_annotate_channels_strict_list_enabled();
576 if (isLevel2ListEnabled &&
577 (aFlag & nsIClassifiedChannel::ClassificationFlags::
578 CLASSIFIED_ANY_STRICT_TRACKING)) {
579 return true;
582 if (StaticPrefs::privacy_socialtracking_block_cookies_enabled() &&
583 IsSocialTrackingClassificationFlag(aFlag)) {
584 return true;
587 return (
588 aFlag &
589 nsIClassifiedChannel::ClassificationFlags::CLASSIFIED_ANY_BASIC_TRACKING);
592 // static
593 bool UrlClassifierCommon::IsSocialTrackingClassificationFlag(uint32_t aFlag) {
594 return (aFlag & nsIClassifiedChannel::ClassificationFlags::
595 CLASSIFIED_ANY_SOCIAL_TRACKING) != 0;
598 // static
599 bool UrlClassifierCommon::IsCryptominingClassificationFlag(uint32_t aFlag,
600 bool aIsPrivate) {
601 if (aFlag &
602 nsIClassifiedChannel::ClassificationFlags::CLASSIFIED_CRYPTOMINING) {
603 return true;
606 bool isLevel2ListEnabled =
607 aIsPrivate
608 ? StaticPrefs::privacy_annotate_channels_strict_list_pbmode_enabled()
609 : StaticPrefs::privacy_annotate_channels_strict_list_enabled();
611 if (isLevel2ListEnabled &&
612 (aFlag & nsIClassifiedChannel::ClassificationFlags::
613 CLASSIFIED_CRYPTOMINING_CONTENT)) {
614 return true;
617 return false;
620 void UrlClassifierCommon::TablesToString(const nsTArray<nsCString>& aList,
621 nsACString& aString) {
622 // Truncate and append rather than assigning because that's more efficient if
623 // aString is an nsAutoCString.
624 aString.Truncate();
625 StringJoinAppend(aString, ","_ns, aList);
628 uint32_t UrlClassifierCommon::TablesToClassificationFlags(
629 const nsTArray<nsCString>& aList,
630 const std::vector<ClassificationData>& aData, uint32_t aDefaultFlag) {
631 uint32_t flags = 0;
632 for (const nsCString& table : aList) {
633 flags |= TableToClassificationFlag(table, aData);
636 if (flags == 0) {
637 flags |= aDefaultFlag;
640 return flags;
643 uint32_t UrlClassifierCommon::TableToClassificationFlag(
644 const nsACString& aTable, const std::vector<ClassificationData>& aData) {
645 for (const ClassificationData& data : aData) {
646 if (StringBeginsWith(aTable, data.mPrefix)) {
647 return data.mFlag;
651 return 0;
654 /* static */
655 bool UrlClassifierCommon::IsPassiveContent(nsIChannel* aChannel) {
656 MOZ_ASSERT(aChannel);
658 nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
659 ExtContentPolicyType contentType = loadInfo->GetExternalContentPolicyType();
661 // Return true if aChannel is loading passive display content, as
662 // defined by the mixed content blocker.
663 // https://searchfox.org/mozilla-central/rev/c80fa7258c935223fe319c5345b58eae85d4c6ae/dom/security/nsMixedContentBlocker.cpp#532
664 return contentType == ExtContentPolicy::TYPE_IMAGE ||
665 contentType == ExtContentPolicy::TYPE_MEDIA ||
666 (contentType == ExtContentPolicy::TYPE_OBJECT_SUBREQUEST &&
667 !StaticPrefs::security_mixed_content_block_object_subrequest());
670 } // namespace net
671 } // namespace mozilla