Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  UrlClassifierCommon.cpp

  Sprache: C
 

/* 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/. */


#include "mozilla/net/UrlClassifierCommon.h"

#include "mozilla/BasePrincipal.h"
#include "mozilla/Components.h"
#include "mozilla/dom/WindowGlobalParent.h"
#include "mozilla/StaticPrefs_privacy.h"
#include "nsIChannel.h"
#include "nsIClassifiedChannel.h"
#include "nsIHttpChannelInternal.h"
#include "nsIParentChannel.h"
#include "nsNetUtil.h"
#include "nsReadableUtils.h"

namespace mozilla {
namespace net {

const nsCString::size_type UrlClassifierCommon::sMaxSpecLength = 128;

// MOZ_LOG=nsChannelClassifier:5
LazyLogModule gChannelClassifierLog("nsChannelClassifier");
LazyLogModule gChannelClassifierLogLeak("nsChannelClassifierLeak");

/* 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) {
    return false;
  }

  return BasePrincipal::Cast(loadingPrincipal)->AddonAllowsLoad(aURI, true);
}

/* static */
bool UrlClassifierCommon::ShouldEnableProtectionForChannel(
    nsIChannel* aChannel) {
  MOZ_ASSERT(aChannel);

  nsCOMPtr<nsIURI> chanURI;
  nsresult rv = aChannel->GetURI(getter_AddRefs(chanURI));
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return false;
  }

  if (UrlClassifierCommon::AddonMayLoad(aChannel, chanURI)) {
    return false;
  }

  nsCOMPtr<nsIURI> topWinURI;
  nsCOMPtr<nsIHttpChannelInternal> channel = do_QueryInterface(aChannel);
  if (NS_WARN_IF(!channel)) {
    return false;
  }

  nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
  MOZ_ASSERT(loadInfo);

  auto policyType = loadInfo->GetExternalContentPolicyType();
  if (policyType == ExtContentPolicy::TYPE_DOCUMENT) {
    UC_LOG(
        ("UrlClassifierCommon::ShouldEnableProtectionForChannel - "
         "skipping top-level load for channel %p",
         aChannel));
    return false;
  }

  // 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.

  return true;
}

/* static */
nsresult UrlClassifierCommon::GetTopWindowURI(nsIChannel* aChannel,
                                              nsIURI** aURI) {
  MOZ_ASSERT(XRE_IsParentProcess());
  MOZ_ASSERT(aChannel);

  nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
  MOZ_ASSERT(loadInfo);

  RefPtr<dom::BrowsingContext> browsingContext;
  nsresult rv =
      loadInfo->GetTargetBrowsingContext(getter_AddRefs(browsingContext));
  if (NS_WARN_IF(NS_FAILED(rv)) || !browsingContext) {
    return NS_ERROR_FAILURE;
  }

  dom::CanonicalBrowsingContext* top = browsingContext->Canonical()->Top();
  dom::WindowGlobalParent* wgp = top->GetCurrentWindowGlobal();
  if (!wgp) {
    return NS_ERROR_FAILURE;
  }

  RefPtr<nsIURI> uri = wgp->GetDocumentURI();
  if (!uri) {
    return NS_ERROR_FAILURE;
  }

  uri.forget(aURI);
  return NS_OK;
}

/* static */
nsresult UrlClassifierCommon::CreatePairwiseEntityListURI(nsIChannel* aChannel,
                                                          nsIURI** aURI) {
  MOZ_ASSERT(aChannel);
  MOZ_ASSERT(aURI);

  nsresult rv;
  nsCOMPtr<nsIHttpChannelInternal> chan = do_QueryInterface(aChannel, &rv);
  NS_ENSURE_SUCCESS(rv, rv);
  if (!chan) {
    return NS_ERROR_FAILURE;
  }

  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));
            (void)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));
        (void)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;
  }

  nsCOMPtr<nsIScriptSecurityManager> securityManager;
  securityManager = mozilla::components::ScriptSecurityManager::Service(&rv);
  NS_ENSURE_SUCCESS(rv, rv);
  nsCOMPtr<nsIPrincipal> chanPrincipal;
  rv = securityManager->GetChannelURIPrincipal(aChannel,
                                               getter_AddRefs(chanPrincipal));
  NS_ENSURE_SUCCESS(rv, rv);

  // 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));

  nsCOMPtr<nsIURI> entitylistURI;
  rv = NS_NewURI(getter_AddRefs(entitylistURI), entitylistEntry);
  if (NS_FAILED(rv)) {
    return rv;
  }

  entitylistURI.forget(aURI);
  return NS_OK;
}

/* static */
nsresult UrlClassifierCommon::SetTrackingInfo(
    nsIChannel* aChannel, const nsTArray<nsCString>& aLists,
    const nsTArray<nsCString>& aFullHashes) {
  NS_ENSURE_ARG(!aLists.IsEmpty());

  // 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;
    UrlClassifierCommon::TablesToString(aLists, strLists);
    UrlClassifierCommon::TablesToString(aFullHashes, strHashes);

    parentChannel->SetClassifierMatchedTrackingInfo(strLists, strHashes);
  }

  return NS_OK;
}

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);
}

uint32_t UrlClassifierCommon::TablesToClassificationFlags(
    const nsTArray<nsCString>& aList,
    const std::vector<ClassificationData>& aData, uint32_t aDefaultFlag) {
  uint32_t flags = 0;
  for (const nsCString& table : aList) {
    flags |= TableToClassificationFlag(table, aData);
  }

  if (flags == 0) {
    flags |= aDefaultFlag;
  }

  return flags;
}

uint32_t UrlClassifierCommon::TableToClassificationFlag(
    const nsACString& aTable, const std::vector<ClassificationData>& aData) {
  for (const ClassificationData& data : aData) {
    if (StringBeginsWith(aTable, data.mPrefix)) {
      return data.mFlag;
    }
  }

  return 0;
}

/* static */
bool UrlClassifierCommon::ShouldProcessWithProtectionFeature(
    nsIChannel* aChannel) {
  MOZ_ASSERT(aChannel);

  bool shouldProcess = true;
  bool isPrivateMode = NS_UsePrivateBrowsing(aChannel);

  nsCOMPtr<nsIClassifiedChannel> classifiedChannel =
      do_QueryInterface(aChannel);

  if (classifiedChannel) {
    if (classifiedChannel->GetClassificationFlags() &
        nsIClassifiedChannel::ClassificationFlags::CLASSIFIED_CONSENTMANAGER) {
      // Channel is classified as consent manager
      if (StaticPrefs::
              privacy_trackingprotection_consentmanager_skip_enabled() ||
          (StaticPrefs::
               privacy_trackingprotection_consentmanager_skip_pbmode_enabled() &&
           isPrivateMode)) {
        // Don't process channel
        shouldProcess = false;

        UC_LOG(
            ("UrlClassifierCommon::ShouldProcessWithProtectionFeature - "
             "Skipping channel %p because annotated as a consent manager",
             aChannel));
      }
    }

    if (classifiedChannel->GetClassificationFlags() &
        nsIClassifiedChannel::ClassificationFlags::CLASSIFIED_ANTIFRAUD) {
      // Channel is classified as anti-fraud
      if (StaticPrefs::privacy_trackingprotection_antifraud_skip_enabled() ||
          (StaticPrefs::
               privacy_trackingprotection_antifraud_skip_pbmode_enabled() &&
           isPrivateMode)) {
        // Don't process channel
        shouldProcess = false;

        UC_LOG(
            ("UrlClassifierCommon::ShouldProcessWithProtectionFeature - "
             "Skipping channel %p because it is annotated as anti-fraud",
             aChannel));
      }
    }
  }

  return shouldProcess;
}

}  // namespace net
}  // namespace mozilla

Messung V0.5 in Prozent
C=91 H=95 G=92

¤ Dauer der Verarbeitung: 0.4 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

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 und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=141584
#Domains=738142