tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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