UrlClassifierFeatureFactory.cpp (13601B)
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/. */ 6 7 #include "mozilla/net/UrlClassifierFeatureFactory.h" 8 9 // List of Features 10 #include "UrlClassifierFeatureAntiFraudAnnotation.h" 11 #include "UrlClassifierFeatureCryptominingAnnotation.h" 12 #include "UrlClassifierFeatureCryptominingProtection.h" 13 #include "UrlClassifierFeatureConsentManagerAnnotation.h" 14 #include "UrlClassifierFeatureEmailTrackingDataCollection.h" 15 #include "UrlClassifierFeatureEmailTrackingProtection.h" 16 #include "UrlClassifierFeatureFingerprintingAnnotation.h" 17 #include "UrlClassifierFeatureFingerprintingProtection.h" 18 #include "UrlClassifierFeatureHarmfulAddonProtection.h" 19 #include "UrlClassifierFeaturePhishingProtection.h" 20 #include "UrlClassifierFeatureSocialTrackingAnnotation.h" 21 #include "UrlClassifierFeatureSocialTrackingProtection.h" 22 #include "UrlClassifierFeatureTrackingProtection.h" 23 #include "UrlClassifierFeatureTrackingAnnotation.h" 24 #include "UrlClassifierFeatureCustomTables.h" 25 26 #include "nsIWebProgressListener.h" 27 #include "nsAppRunner.h" 28 29 namespace mozilla { 30 namespace net { 31 32 /* static */ 33 void UrlClassifierFeatureFactory::Shutdown() { 34 // We want to expose Features only in the parent process. 35 if (!XRE_IsParentProcess()) { 36 return; 37 } 38 39 UrlClassifierFeatureCryptominingAnnotation::MaybeShutdown(); 40 UrlClassifierFeatureCryptominingProtection::MaybeShutdown(); 41 UrlClassifierFeatureConsentManagerAnnotation::MaybeShutdown(); 42 UrlClassifierFeatureAntiFraudAnnotation::MaybeShutdown(); 43 UrlClassifierFeatureEmailTrackingDataCollection::MaybeShutdown(); 44 UrlClassifierFeatureEmailTrackingProtection::MaybeShutdown(); 45 UrlClassifierFeatureFingerprintingAnnotation::MaybeShutdown(); 46 UrlClassifierFeatureFingerprintingProtection::MaybeShutdown(); 47 UrlClassifierFeaturePhishingProtection::MaybeShutdown(); 48 UrlClassifierFeatureSocialTrackingAnnotation::MaybeShutdown(); 49 UrlClassifierFeatureSocialTrackingProtection::MaybeShutdown(); 50 UrlClassifierFeatureTrackingAnnotation::MaybeShutdown(); 51 UrlClassifierFeatureTrackingProtection::MaybeShutdown(); 52 UrlClassifierFeatureHarmfulAddonProtection::MaybeShutdown(); 53 } 54 55 /* static */ 56 void UrlClassifierFeatureFactory::GetFeaturesFromChannel( 57 nsIChannel* aChannel, 58 nsTArray<nsCOMPtr<nsIUrlClassifierFeature>>& aFeatures) { 59 MOZ_ASSERT(XRE_IsParentProcess()); 60 MOZ_ASSERT(aChannel); 61 62 nsCOMPtr<nsIUrlClassifierFeature> feature; 63 64 // Note that the order of the features is extremely important! When more than 65 // 1 feature classifies the channel, we call ::ProcessChannel() following this 66 // feature order, and this could produce different results with a different 67 // feature ordering. 68 69 // Email Tracking Data Collection 70 // This needs to be run before other features so that other blocking features 71 // won't stop us to collect data for email trackers. Note that this feature 72 // is not a blocking feature. 73 feature = 74 UrlClassifierFeatureEmailTrackingDataCollection::MaybeCreate(aChannel); 75 if (feature) { 76 aFeatures.AppendElement(feature); 77 } 78 79 // Consent Manager Annotation 80 // This must be run before any blocking features because the annotation will 81 // affect whether the channel should be blocked. 82 feature = UrlClassifierFeatureConsentManagerAnnotation::MaybeCreate(aChannel); 83 if (feature) { 84 aFeatures.AppendElement(feature); 85 } 86 87 // Anti-fraud Annotation 88 // This must be run before any blocking features because the annotation will 89 // affect whether the channel should be blocked. 90 feature = UrlClassifierFeatureAntiFraudAnnotation::MaybeCreate(aChannel); 91 if (feature) { 92 aFeatures.AppendElement(feature); 93 } 94 95 // Email Tracking Protection 96 feature = UrlClassifierFeatureEmailTrackingProtection::MaybeCreate(aChannel); 97 if (feature) { 98 aFeatures.AppendElement(feature); 99 } 100 101 // Cryptomining Protection 102 feature = UrlClassifierFeatureCryptominingProtection::MaybeCreate(aChannel); 103 if (feature) { 104 aFeatures.AppendElement(feature); 105 } 106 107 // Fingerprinting Protection 108 feature = UrlClassifierFeatureFingerprintingProtection::MaybeCreate(aChannel); 109 if (feature) { 110 aFeatures.AppendElement(feature); 111 } 112 113 // SocialTracking Protection 114 feature = UrlClassifierFeatureSocialTrackingProtection::MaybeCreate(aChannel); 115 if (feature) { 116 aFeatures.AppendElement(feature); 117 } 118 119 // Addon Protection 120 feature = UrlClassifierFeatureHarmfulAddonProtection::MaybeCreate(aChannel); 121 if (feature) { 122 aFeatures.AppendElement(feature); 123 } 124 125 // Tracking Protection 126 feature = UrlClassifierFeatureTrackingProtection::MaybeCreate(aChannel); 127 if (feature) { 128 aFeatures.AppendElement(feature); 129 } 130 131 // Cryptomining Annotation 132 feature = UrlClassifierFeatureCryptominingAnnotation::MaybeCreate(aChannel); 133 if (feature) { 134 aFeatures.AppendElement(feature); 135 } 136 137 // Fingerprinting Annotation 138 feature = UrlClassifierFeatureFingerprintingAnnotation::MaybeCreate(aChannel); 139 if (feature) { 140 aFeatures.AppendElement(feature); 141 } 142 143 // SocialTracking Annotation 144 feature = UrlClassifierFeatureSocialTrackingAnnotation::MaybeCreate(aChannel); 145 if (feature) { 146 aFeatures.AppendElement(feature); 147 } 148 149 // Tracking Annotation 150 feature = UrlClassifierFeatureTrackingAnnotation::MaybeCreate(aChannel); 151 if (feature) { 152 aFeatures.AppendElement(feature); 153 } 154 } 155 156 /* static */ 157 void UrlClassifierFeatureFactory::GetPhishingProtectionFeatures( 158 nsTArray<RefPtr<nsIUrlClassifierFeature>>& aFeatures) { 159 UrlClassifierFeaturePhishingProtection::MaybeCreate(aFeatures); 160 } 161 162 /* static */ 163 already_AddRefed<nsIUrlClassifierFeature> 164 UrlClassifierFeatureFactory::GetFeatureByName(const nsACString& aName) { 165 if (!XRE_IsParentProcess()) { 166 return nullptr; 167 } 168 169 nsCOMPtr<nsIUrlClassifierFeature> feature; 170 171 // Anti-fraud Annotation 172 feature = UrlClassifierFeatureAntiFraudAnnotation::GetIfNameMatches(aName); 173 if (feature) { 174 return feature.forget(); 175 } 176 177 // Cryptomining Annotation 178 feature = UrlClassifierFeatureCryptominingAnnotation::GetIfNameMatches(aName); 179 if (feature) { 180 return feature.forget(); 181 } 182 183 // Cryptomining Protection 184 feature = UrlClassifierFeatureCryptominingProtection::GetIfNameMatches(aName); 185 if (feature) { 186 return feature.forget(); 187 } 188 189 // Consent Manager Annotation 190 feature = 191 UrlClassifierFeatureConsentManagerAnnotation::GetIfNameMatches(aName); 192 if (feature) { 193 return feature.forget(); 194 } 195 196 // Email Tracking Data Collection 197 feature = 198 UrlClassifierFeatureEmailTrackingDataCollection::GetIfNameMatches(aName); 199 if (feature) { 200 return feature.forget(); 201 } 202 203 // Email Tracking Protection 204 feature = 205 UrlClassifierFeatureEmailTrackingProtection::GetIfNameMatches(aName); 206 if (feature) { 207 return feature.forget(); 208 } 209 210 // Fingerprinting Annotation 211 feature = 212 UrlClassifierFeatureFingerprintingAnnotation::GetIfNameMatches(aName); 213 if (feature) { 214 return feature.forget(); 215 } 216 217 // Fingerprinting Protection 218 feature = 219 UrlClassifierFeatureFingerprintingProtection::GetIfNameMatches(aName); 220 if (feature) { 221 return feature.forget(); 222 } 223 224 // SocialTracking Annotation 225 feature = 226 UrlClassifierFeatureSocialTrackingAnnotation::GetIfNameMatches(aName); 227 if (feature) { 228 return feature.forget(); 229 } 230 231 // SocialTracking Protection 232 feature = 233 UrlClassifierFeatureSocialTrackingProtection::GetIfNameMatches(aName); 234 if (feature) { 235 return feature.forget(); 236 } 237 238 // Tracking Protection 239 feature = UrlClassifierFeatureTrackingProtection::GetIfNameMatches(aName); 240 if (feature) { 241 return feature.forget(); 242 } 243 244 // Tracking Annotation 245 feature = UrlClassifierFeatureTrackingAnnotation::GetIfNameMatches(aName); 246 if (feature) { 247 return feature.forget(); 248 } 249 250 // PhishingProtection features 251 feature = UrlClassifierFeaturePhishingProtection::GetIfNameMatches(aName); 252 if (feature) { 253 return feature.forget(); 254 } 255 256 // Addon Protection 257 feature = UrlClassifierFeatureHarmfulAddonProtection::GetIfNameMatches(aName); 258 if (feature) { 259 return feature.forget(); 260 } 261 262 return nullptr; 263 } 264 265 /* static */ 266 void UrlClassifierFeatureFactory::GetFeatureNames(nsTArray<nsCString>& aArray) { 267 if (!XRE_IsParentProcess()) { 268 return; 269 } 270 271 nsAutoCString name; 272 273 // Anti-fraud Annotation 274 name.Assign(UrlClassifierFeatureAntiFraudAnnotation::Name()); 275 if (!name.IsEmpty()) { 276 aArray.AppendElement(name); 277 } 278 279 // Cryptomining Annotation 280 name.Assign(UrlClassifierFeatureCryptominingAnnotation::Name()); 281 if (!name.IsEmpty()) { 282 aArray.AppendElement(name); 283 } 284 285 // Cryptomining Protection 286 name.Assign(UrlClassifierFeatureCryptominingProtection::Name()); 287 if (!name.IsEmpty()) { 288 aArray.AppendElement(name); 289 } 290 291 // Consent Manager Annotation 292 name.Assign(UrlClassifierFeatureConsentManagerAnnotation::Name()); 293 if (!name.IsEmpty()) { 294 aArray.AppendElement(name); 295 } 296 297 // Email Tracking Data Collection 298 name.Assign(UrlClassifierFeatureEmailTrackingDataCollection::Name()); 299 if (!name.IsEmpty()) { 300 aArray.AppendElement(name); 301 } 302 303 // Email Tracking Protection 304 name.Assign(UrlClassifierFeatureEmailTrackingProtection::Name()); 305 if (!name.IsEmpty()) { 306 aArray.AppendElement(name); 307 } 308 309 // Fingerprinting Annotation 310 name.Assign(UrlClassifierFeatureFingerprintingAnnotation::Name()); 311 if (!name.IsEmpty()) { 312 aArray.AppendElement(name); 313 } 314 315 // Fingerprinting Protection 316 name.Assign(UrlClassifierFeatureFingerprintingProtection::Name()); 317 if (!name.IsEmpty()) { 318 aArray.AppendElement(name); 319 } 320 321 // SocialTracking Annotation 322 name.Assign(UrlClassifierFeatureSocialTrackingAnnotation::Name()); 323 if (!name.IsEmpty()) { 324 aArray.AppendElement(name); 325 } 326 327 // SocialTracking Protection 328 name.Assign(UrlClassifierFeatureSocialTrackingProtection::Name()); 329 if (!name.IsEmpty()) { 330 aArray.AppendElement(name); 331 } 332 333 // Tracking Protection 334 name.Assign(UrlClassifierFeatureTrackingProtection::Name()); 335 if (!name.IsEmpty()) { 336 aArray.AppendElement(name); 337 } 338 339 // Tracking Annotation 340 name.Assign(UrlClassifierFeatureTrackingAnnotation::Name()); 341 if (!name.IsEmpty()) { 342 aArray.AppendElement(name); 343 } 344 345 // Addon Protection 346 name.Assign(UrlClassifierFeatureHarmfulAddonProtection::Name()); 347 if (!name.IsEmpty()) { 348 aArray.AppendElement(name); 349 } 350 351 // PhishingProtection features 352 { 353 nsTArray<nsCString> features; 354 UrlClassifierFeaturePhishingProtection::GetFeatureNames(features); 355 aArray.AppendElements(features); 356 } 357 } 358 359 /* static */ 360 already_AddRefed<nsIUrlClassifierFeature> 361 UrlClassifierFeatureFactory::CreateFeatureWithTables( 362 const nsACString& aName, const nsTArray<nsCString>& aBlocklistTables, 363 const nsTArray<nsCString>& aEntitylistTables) { 364 nsCOMPtr<nsIUrlClassifierFeature> feature = 365 new UrlClassifierFeatureCustomTables(aName, aBlocklistTables, 366 aEntitylistTables); 367 return feature.forget(); 368 } 369 370 namespace { 371 372 struct BlockingErrorCode { 373 nsresult mErrorCode; 374 uint32_t mBlockingEventCode; 375 const char* mConsoleMessage; 376 nsLiteralCString mConsoleCategory; 377 }; 378 379 static constexpr BlockingErrorCode sBlockingErrorCodes[] = { 380 {NS_ERROR_TRACKING_URI, 381 nsIWebProgressListener::STATE_BLOCKED_TRACKING_CONTENT, 382 "TrackerUriBlockedByETP", "Tracking Protection"_ns}, 383 {NS_ERROR_FINGERPRINTING_URI, 384 nsIWebProgressListener::STATE_BLOCKED_FINGERPRINTING_CONTENT, 385 "TrackerUriBlockedByETP", "Tracking Protection"_ns}, 386 {NS_ERROR_CRYPTOMINING_URI, 387 nsIWebProgressListener::STATE_BLOCKED_CRYPTOMINING_CONTENT, 388 "TrackerUriBlockedByETP", "Tracking Protection"_ns}, 389 {NS_ERROR_SOCIALTRACKING_URI, 390 nsIWebProgressListener::STATE_BLOCKED_SOCIALTRACKING_CONTENT, 391 "TrackerUriBlockedByETP", "Tracking Protection"_ns}, 392 {NS_ERROR_EMAILTRACKING_URI, 393 nsIWebProgressListener::STATE_BLOCKED_EMAILTRACKING_CONTENT, 394 "TrackerUriBlockedByETP", "Tracking Protection"_ns}, 395 }; 396 397 } // namespace 398 399 /* static */ 400 bool UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode( 401 nsresult aError) { 402 // In theory we can iterate through the features, but at the moment, we can 403 // just have a simple check here. 404 for (const auto& blockingErrorCode : sBlockingErrorCodes) { 405 if (aError == blockingErrorCode.mErrorCode) { 406 return true; 407 } 408 } 409 410 return false; 411 } 412 413 /* static */ 414 bool UrlClassifierFeatureFactory::IsClassifierBlockingEventCode( 415 uint32_t aEventCode) { 416 for (const auto& blockingErrorCode : sBlockingErrorCodes) { 417 if (aEventCode == blockingErrorCode.mBlockingEventCode) { 418 return true; 419 } 420 } 421 return false; 422 } 423 424 /* static */ 425 uint32_t UrlClassifierFeatureFactory::GetClassifierBlockingEventCode( 426 nsresult aErrorCode) { 427 for (const auto& blockingErrorCode : sBlockingErrorCodes) { 428 if (aErrorCode == blockingErrorCode.mErrorCode) { 429 return blockingErrorCode.mBlockingEventCode; 430 } 431 } 432 return 0; 433 } 434 435 /* static */ const char* 436 UrlClassifierFeatureFactory::ClassifierBlockingErrorCodeToConsoleMessage( 437 nsresult aError, nsACString& aCategory) { 438 for (const auto& blockingErrorCode : sBlockingErrorCodes) { 439 if (aError == blockingErrorCode.mErrorCode) { 440 aCategory = blockingErrorCode.mConsoleCategory; 441 return blockingErrorCode.mConsoleMessage; 442 } 443 } 444 445 return nullptr; 446 } 447 448 } // namespace net 449 } // namespace mozilla