UrlClassifierFeatureSocialTrackingProtection.cpp (7641B)
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 "UrlClassifierFeatureSocialTrackingProtection.h" 8 9 #include "mozilla/AntiTrackingUtils.h" 10 #include "mozilla/net/UrlClassifierCommon.h" 11 #include "ChannelClassifierService.h" 12 #include "mozilla/StaticPrefs_privacy.h" 13 #include "nsNetUtil.h" 14 #include "mozilla/StaticPtr.h" 15 #include "nsIWebProgressListener.h" 16 #include "nsIHttpChannelInternal.h" 17 #include "nsIChannel.h" 18 19 namespace mozilla { 20 namespace net { 21 22 namespace { 23 24 #define SOCIALTRACKING_FEATURE_NAME "socialtracking-protection" 25 26 #define URLCLASSIFIER_SOCIALTRACKING_BLOCKLIST \ 27 "urlclassifier.features.socialtracking.blacklistTables" 28 #define URLCLASSIFIER_SOCIALTRACKING_BLOCKLIST_TEST_ENTRIES \ 29 "urlclassifier.features.socialtracking.blacklistHosts" 30 #define URLCLASSIFIER_SOCIALTRACKING_ENTITYLIST \ 31 "urlclassifier.features.socialtracking.whitelistTables" 32 #define URLCLASSIFIER_SOCIALTRACKING_ENTITYLIST_TEST_ENTRIES \ 33 "urlclassifier.features.socialtracking.whitelistHosts" 34 #define URLCLASSIFIER_SOCIALTRACKING_EXCEPTION_URLS \ 35 "urlclassifier.features.socialtracking.skipURLs" 36 #define TABLE_SOCIALTRACKING_BLOCKLIST_PREF "socialtracking-blocklist-pref" 37 #define TABLE_SOCIALTRACKING_ENTITYLIST_PREF "socialtracking-entitylist-pref" 38 39 StaticRefPtr<UrlClassifierFeatureSocialTrackingProtection> 40 gFeatureSocialTrackingProtection; 41 42 } // namespace 43 44 UrlClassifierFeatureSocialTrackingProtection:: 45 UrlClassifierFeatureSocialTrackingProtection() 46 : UrlClassifierFeatureAntiTrackingBase( 47 nsLiteralCString(SOCIALTRACKING_FEATURE_NAME), 48 nsLiteralCString(URLCLASSIFIER_SOCIALTRACKING_BLOCKLIST), 49 nsLiteralCString(URLCLASSIFIER_SOCIALTRACKING_ENTITYLIST), 50 nsLiteralCString(URLCLASSIFIER_SOCIALTRACKING_BLOCKLIST_TEST_ENTRIES), 51 nsLiteralCString( 52 URLCLASSIFIER_SOCIALTRACKING_ENTITYLIST_TEST_ENTRIES), 53 nsLiteralCString(TABLE_SOCIALTRACKING_BLOCKLIST_PREF), 54 nsLiteralCString(TABLE_SOCIALTRACKING_ENTITYLIST_PREF), 55 nsLiteralCString(URLCLASSIFIER_SOCIALTRACKING_EXCEPTION_URLS)) {} 56 57 /* static */ const char* UrlClassifierFeatureSocialTrackingProtection::Name() { 58 return SOCIALTRACKING_FEATURE_NAME; 59 } 60 61 /* static */ 62 void UrlClassifierFeatureSocialTrackingProtection::MaybeInitialize() { 63 UC_LOG_LEAK( 64 ("UrlClassifierFeatureSocialTrackingProtection::MaybeInitialize")); 65 66 if (!gFeatureSocialTrackingProtection) { 67 gFeatureSocialTrackingProtection = 68 new UrlClassifierFeatureSocialTrackingProtection(); 69 gFeatureSocialTrackingProtection->InitializePreferences(); 70 } 71 } 72 73 /* static */ 74 void UrlClassifierFeatureSocialTrackingProtection::MaybeShutdown() { 75 UC_LOG_LEAK(("UrlClassifierFeatureSocialTrackingProtection::MaybeShutdown")); 76 77 if (gFeatureSocialTrackingProtection) { 78 gFeatureSocialTrackingProtection->ShutdownPreferences(); 79 gFeatureSocialTrackingProtection = nullptr; 80 } 81 } 82 83 /* static */ 84 already_AddRefed<UrlClassifierFeatureSocialTrackingProtection> 85 UrlClassifierFeatureSocialTrackingProtection::MaybeCreate( 86 nsIChannel* aChannel) { 87 MOZ_ASSERT(aChannel); 88 89 UC_LOG_LEAK( 90 ("UrlClassifierFeatureSocialTrackingProtection::MaybeCreate - channel %p", 91 aChannel)); 92 93 if (!StaticPrefs::privacy_trackingprotection_socialtracking_enabled()) { 94 return nullptr; 95 } 96 97 RefPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo(); 98 bool isThirdParty = loadInfo->GetIsThirdPartyContextToTopWindow(); 99 if (!isThirdParty) { 100 UC_LOG( 101 ("UrlClassifierFeatureSocialTrackingProtection::MaybeCreate - " 102 "skipping first party or top-level load for channel %p", 103 aChannel)); 104 return nullptr; 105 } 106 107 if (!UrlClassifierCommon::ShouldEnableProtectionForChannel(aChannel)) { 108 return nullptr; 109 } 110 111 MaybeInitialize(); 112 MOZ_ASSERT(gFeatureSocialTrackingProtection); 113 114 RefPtr<UrlClassifierFeatureSocialTrackingProtection> self = 115 gFeatureSocialTrackingProtection; 116 return self.forget(); 117 } 118 119 /* static */ 120 already_AddRefed<nsIUrlClassifierFeature> 121 UrlClassifierFeatureSocialTrackingProtection::GetIfNameMatches( 122 const nsACString& aName) { 123 if (!aName.EqualsLiteral(SOCIALTRACKING_FEATURE_NAME)) { 124 return nullptr; 125 } 126 127 MaybeInitialize(); 128 MOZ_ASSERT(gFeatureSocialTrackingProtection); 129 130 RefPtr<UrlClassifierFeatureSocialTrackingProtection> self = 131 gFeatureSocialTrackingProtection; 132 return self.forget(); 133 } 134 135 NS_IMETHODIMP 136 UrlClassifierFeatureSocialTrackingProtection::ProcessChannel( 137 nsIChannel* aChannel, const nsTArray<nsCString>& aList, 138 const nsTArray<nsCString>& aHashes, bool* aShouldContinue) { 139 NS_ENSURE_ARG_POINTER(aChannel); 140 NS_ENSURE_ARG_POINTER(aShouldContinue); 141 142 bool isAllowListed = UrlClassifierCommon::IsAllowListed(aChannel); 143 144 // This is a blocking feature. 145 *aShouldContinue = isAllowListed; 146 147 if (isAllowListed) { 148 return NS_OK; 149 } 150 151 bool ShouldProcessByProtectionFeature = 152 UrlClassifierCommon::ShouldProcessWithProtectionFeature(aChannel); 153 154 *aShouldContinue = !ShouldProcessByProtectionFeature; 155 156 if (!ShouldProcessByProtectionFeature) { 157 return NS_OK; 158 } 159 160 nsAutoCString list; 161 UrlClassifierCommon::TablesToString(aList, list); 162 163 ChannelBlockDecision decision = 164 ChannelClassifierService::OnBeforeBlockChannel(aChannel, mName, list); 165 if (decision != ChannelBlockDecision::Blocked) { 166 uint32_t event = 167 decision == ChannelBlockDecision::Replaced 168 ? nsIWebProgressListener::STATE_REPLACED_TRACKING_CONTENT 169 : nsIWebProgressListener::STATE_ALLOWED_TRACKING_CONTENT; 170 171 // Need to set aBlocked to True if we replace the Social Tracker 172 // with a shim, since the shim is treated as a blocked event 173 // Note: If we need to account for which kind of tracker was replaced, 174 // we need to create a new event type in nsIWebProgressListener 175 if (event == nsIWebProgressListener::STATE_REPLACED_TRACKING_CONTENT) { 176 ContentBlockingNotifier::OnEvent(aChannel, event, true); 177 } else { 178 ContentBlockingNotifier::OnEvent(aChannel, event, false); 179 } 180 181 *aShouldContinue = true; 182 return NS_OK; 183 } 184 185 UrlClassifierCommon::SetBlockedContent(aChannel, NS_ERROR_SOCIALTRACKING_URI, 186 list, ""_ns, ""_ns); 187 188 UC_LOG( 189 ("UrlClassifierFeatureSocialTrackingProtection::ProcessChannel - " 190 "cancelling channel %p", 191 aChannel)); 192 nsCOMPtr<nsIHttpChannelInternal> httpChannel = do_QueryInterface(aChannel); 193 194 if (httpChannel) { 195 (void)httpChannel->CancelByURLClassifier(NS_ERROR_SOCIALTRACKING_URI); 196 } else { 197 (void)aChannel->Cancel(NS_ERROR_SOCIALTRACKING_URI); 198 } 199 200 return NS_OK; 201 } 202 203 NS_IMETHODIMP 204 UrlClassifierFeatureSocialTrackingProtection::GetURIByListType( 205 nsIChannel* aChannel, nsIUrlClassifierFeature::listType aListType, 206 nsIUrlClassifierFeature::URIType* aURIType, nsIURI** aURI) { 207 NS_ENSURE_ARG_POINTER(aChannel); 208 NS_ENSURE_ARG_POINTER(aURIType); 209 NS_ENSURE_ARG_POINTER(aURI); 210 211 if (aListType == nsIUrlClassifierFeature::blocklist) { 212 *aURIType = nsIUrlClassifierFeature::blocklistURI; 213 return aChannel->GetURI(aURI); 214 } 215 216 MOZ_ASSERT(aListType == nsIUrlClassifierFeature::entitylist); 217 218 *aURIType = nsIUrlClassifierFeature::pairwiseEntitylistURI; 219 return UrlClassifierCommon::CreatePairwiseEntityListURI(aChannel, aURI); 220 } 221 222 } // namespace net 223 } // namespace mozilla