1 // Copyright 2017 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef NET_NETWORK_ERROR_LOGGING_NETWORK_ERROR_LOGGING_SERVICE_H_ 6 #define NET_NETWORK_ERROR_LOGGING_NETWORK_ERROR_LOGGING_SERVICE_H_ 7 8 #include <map> 9 #include <memory> 10 #include <set> 11 #include <string> 12 #include <vector> 13 14 #include "base/feature_list.h" 15 #include "base/memory/raw_ptr.h" 16 #include "base/time/clock.h" 17 #include "base/time/time.h" 18 #include "net/base/ip_address.h" 19 #include "net/base/net_errors.h" 20 #include "net/base/net_export.h" 21 #include "net/base/network_anonymization_key.h" 22 #include "url/gurl.h" 23 #include "url/origin.h" 24 25 namespace base { 26 class Value; 27 } // namespace base 28 29 namespace net { 30 class ReportingService; 31 } // namespace net 32 33 namespace url { 34 class Origin; 35 } // namespace url 36 37 namespace features { 38 extern const base::Feature NET_EXPORT kNetworkErrorLogging; 39 } // namespace features 40 41 namespace net { 42 43 class NET_EXPORT NetworkErrorLoggingService { 44 public: 45 class PersistentNelStore; 46 47 // Every (NAK, origin) pair can have at most one policy. 48 struct NET_EXPORT NelPolicyKey { 49 NelPolicyKey(); 50 NelPolicyKey(const NetworkAnonymizationKey& network_anonymization_key, 51 const url::Origin& origin); 52 NelPolicyKey(const NelPolicyKey& other); 53 ~NelPolicyKey(); 54 55 bool operator<(const NelPolicyKey& other) const; 56 bool operator==(const NelPolicyKey& other) const; 57 bool operator!=(const NelPolicyKey& other) const; 58 59 // The NAK of the request this policy was received from. This will be used 60 // for any requests uploading reports according to this policy. (Not 61 // included in the report itself.) 62 NetworkAnonymizationKey network_anonymization_key; 63 64 url::Origin origin; 65 }; 66 67 // Used for wildcard policies that are applicable to |domain| and its 68 // subdomains. 69 struct WildcardNelPolicyKey { 70 WildcardNelPolicyKey(); 71 WildcardNelPolicyKey( 72 const NetworkAnonymizationKey& network_anonymization_key, 73 const std::string& domain); 74 explicit WildcardNelPolicyKey(const NelPolicyKey& origin_key); 75 WildcardNelPolicyKey(const WildcardNelPolicyKey& other); 76 ~WildcardNelPolicyKey(); 77 78 bool operator<(const WildcardNelPolicyKey& other) const; 79 80 // The NAK of the request this policy was received from. This will be used 81 // for any requests uploading reports according to this policy. (Not 82 // included in the report itself.) 83 NetworkAnonymizationKey network_anonymization_key; 84 85 std::string domain; 86 }; 87 88 // NEL policy set by an origin. 89 struct NET_EXPORT NelPolicy { 90 NelPolicy(); 91 NelPolicy(const NelPolicy& other); 92 ~NelPolicy(); 93 94 NelPolicyKey key; 95 96 IPAddress received_ip_address = IPAddress(); 97 98 // Reporting API endpoint group to which reports should be sent. 99 std::string report_to; 100 101 base::Time expires; 102 103 double success_fraction = 0.0; 104 double failure_fraction = 1.0; 105 bool include_subdomains = false; 106 107 // Last time the policy was accessed to create a report, even if no report 108 // ends up being queued. Also updated when the policy is first set. 109 mutable base::Time last_used; 110 }; 111 112 // The details of a network error that are included in an NEL report. 113 // 114 // See http://wicg.github.io/network-error-logging/#dfn-network-error-object 115 // for details on the semantics of each field. 116 struct NET_EXPORT RequestDetails { 117 RequestDetails(); 118 RequestDetails(const RequestDetails& other); 119 ~RequestDetails(); 120 121 // NetworkAnonymizationKey of the request triggering the error. Not included 122 // in the uploaded report. 123 NetworkAnonymizationKey network_anonymization_key; 124 125 GURL uri; 126 GURL referrer; 127 std::string user_agent; 128 IPAddress server_ip; 129 std::string protocol; 130 std::string method; 131 int status_code; 132 base::TimeDelta elapsed_time; 133 Error type; 134 135 // Upload nesting depth of this request. 136 // 137 // If the request is not a Reporting upload, the depth is 0. 138 // 139 // If the request is a Reporting upload, the depth is the max of the depth 140 // of the requests reported within it plus 1. (Non-NEL reports are 141 // considered to have depth 0.) 142 int reporting_upload_depth; 143 }; 144 145 // The details of a signed exchange report. 146 struct NET_EXPORT SignedExchangeReportDetails { 147 SignedExchangeReportDetails(); 148 SignedExchangeReportDetails(const SignedExchangeReportDetails& other); 149 ~SignedExchangeReportDetails(); 150 151 // NetworkAnonymizationKey of the request triggering the error. Not included 152 // in the uploaded report. 153 NetworkAnonymizationKey network_anonymization_key; 154 155 bool success; 156 std::string type; 157 GURL outer_url; 158 GURL inner_url; 159 GURL cert_url; 160 std::string referrer; 161 IPAddress server_ip_address; 162 std::string protocol; 163 std::string method; 164 int32_t status_code; 165 base::TimeDelta elapsed_time; 166 std::string user_agent; 167 }; 168 169 static const char kHeaderName[]; 170 171 static const char kReportType[]; 172 173 static const int kMaxNestedReportDepth; 174 175 // Keys for data included in report bodies. Exposed for tests. 176 177 static const char kReferrerKey[]; 178 static const char kSamplingFractionKey[]; 179 static const char kServerIpKey[]; 180 static const char kProtocolKey[]; 181 static const char kMethodKey[]; 182 static const char kStatusCodeKey[]; 183 static const char kElapsedTimeKey[]; 184 static const char kPhaseKey[]; 185 static const char kTypeKey[]; 186 187 static const char kSignedExchangePhaseValue[]; 188 static const char kSignedExchangeBodyKey[]; 189 static const char kOuterUrlKey[]; 190 static const char kInnerUrlKey[]; 191 static const char kCertUrlKey[]; 192 193 // Maximum number of NEL policies to store before evicting. 194 static const size_t kMaxPolicies; 195 196 static const char kSignedExchangeRequestOutcomeHistogram[]; 197 198 // Used for histogramming Signed Exchange request outcomes only. Previously, 199 // the outcome of all requests would be histogrammed, but this was removed in 200 // crbug.com/1007122 because the histogram was very large and not very useful. 201 enum class RequestOutcome { 202 kDiscardedNoNetworkErrorLoggingService = 0, 203 204 kDiscardedNoReportingService = 1, 205 kDiscardedInsecureOrigin = 2, 206 kDiscardedNoOriginPolicy = 3, 207 kDiscardedUnmappedError = 4, 208 kDiscardedReportingUpload = 5, 209 kDiscardedUnsampledSuccess = 6, 210 kDiscardedUnsampledFailure = 7, 211 kQueued = 8, 212 kDiscardedNonDNSSubdomainReport = 9, 213 kDiscardedIPAddressMismatch = 10, 214 215 kMaxValue = kDiscardedIPAddressMismatch 216 }; 217 218 // NEL policies are persisted to disk if |store| is not null. 219 // The store, if given, should outlive |*this|. 220 static std::unique_ptr<NetworkErrorLoggingService> Create( 221 PersistentNelStore* store); 222 223 NetworkErrorLoggingService(const NetworkErrorLoggingService&) = delete; 224 NetworkErrorLoggingService& operator=(const NetworkErrorLoggingService&) = 225 delete; 226 227 virtual ~NetworkErrorLoggingService(); 228 229 // Ingests a "NEL:" header received for |network_anonymization_key| and 230 // |origin| from |received_ip_address| with normalized value |value|. May or 231 // may not actually set a policy for that origin. 232 virtual void OnHeader( 233 const NetworkAnonymizationKey& network_anonymization_key, 234 const url::Origin& origin, 235 const IPAddress& received_ip_address, 236 const std::string& value) = 0; 237 238 // Considers queueing a network error report for the request described in 239 // |details|. The contents of |details| might be changed, depending on the 240 // NEL policy associated with the request's origin. Note that |details| is 241 // passed by value, so that it doesn't need to be copied in this function if 242 // it needs to be changed. Consider using std::move to pass this parameter if 243 // the caller doesn't need to access it after this method call. 244 // 245 // Note that Network Error Logging can report a fraction of successful 246 // requests as well (to calculate error rates), so this should be called on 247 // *all* secure requests. NEL is only available to secure origins, so this is 248 // not called on any insecure requests. 249 virtual void OnRequest(RequestDetails details) = 0; 250 251 // Queues a Signed Exchange report. 252 virtual void QueueSignedExchangeReport( 253 SignedExchangeReportDetails details) = 0; 254 255 // Removes browsing data (origin policies) associated with any origin for 256 // which |origin_filter| returns true. 257 virtual void RemoveBrowsingData( 258 const base::RepeatingCallback<bool(const url::Origin&)>& 259 origin_filter) = 0; 260 261 // Removes browsing data (origin policies) for all origins. Allows slight 262 // optimization over passing an always-true filter to RemoveBrowsingData. 263 virtual void RemoveAllBrowsingData() = 0; 264 265 // Sets the ReportingService that will be used to queue network error reports. 266 // If |nullptr| is passed, reports will be queued locally or discarded. 267 // |reporting_service| must outlive the NetworkErrorLoggingService. 268 // Should not be called again if previously called with a non-null pointer. 269 void SetReportingService(ReportingService* reporting_service); 270 271 // Shuts down the NEL service, so that no more requests or headers can be 272 // processed, no more reports are queued, and browsing data can no longer be 273 // cleared. 274 void OnShutdown(); 275 276 // Sets a base::Clock (used to track policy expiration) for tests. 277 // |clock| must outlive the NetworkErrorLoggingService, and cannot be 278 // nullptr. 279 void SetClockForTesting(const base::Clock* clock); 280 281 // Dumps info about all the currently stored policies, including expired ones. 282 // Used to display information about NEL policies on the NetLog Reporting tab. 283 virtual base::Value StatusAsValue() const; 284 285 // Gets the (NAK, origin) keys of all currently stored policies, including 286 // expired ones. 287 virtual std::set<NelPolicyKey> GetPolicyKeysForTesting(); 288 289 virtual PersistentNelStore* GetPersistentNelStoreForTesting(); 290 virtual ReportingService* GetReportingServiceForTesting(); 291 292 protected: 293 NetworkErrorLoggingService(); 294 295 // Unowned: 296 raw_ptr<const base::Clock> clock_; 297 raw_ptr<ReportingService, DanglingUntriaged> reporting_service_ = nullptr; 298 bool shut_down_ = false; 299 }; 300 301 // Persistent storage for NEL policies. 302 class NET_EXPORT NetworkErrorLoggingService::PersistentNelStore { 303 public: 304 using NelPoliciesLoadedCallback = 305 base::OnceCallback<void(std::vector<NelPolicy>)>; 306 307 PersistentNelStore() = default; 308 309 PersistentNelStore(const PersistentNelStore&) = delete; 310 PersistentNelStore& operator=(const PersistentNelStore&) = delete; 311 312 virtual ~PersistentNelStore() = default; 313 314 // Initializes the store and retrieves stored NEL policies. This will be 315 // called only once at startup. 316 virtual void LoadNelPolicies(NelPoliciesLoadedCallback loaded_callback) = 0; 317 318 // Adds a NEL policy to the store. 319 virtual void AddNelPolicy(const NelPolicy& policy) = 0; 320 321 // Updates the access time of the NEL policy in the store. 322 virtual void UpdateNelPolicyAccessTime(const NelPolicy& policy) = 0; 323 324 // Deletes a NEL policy from the store. 325 virtual void DeleteNelPolicy(const NelPolicy& policy) = 0; 326 327 // Flushes the store. 328 virtual void Flush() = 0; 329 }; 330 331 } // namespace net 332 333 #endif // NET_NETWORK_ERROR_LOGGING_NETWORK_ERROR_LOGGING_SERVICE_H_ 334