Bug 1594613 - Added telemetry for http basic-auth confirm prompts and URI UserInfo usage. r=valentin
authorPaul Zuehlcke <pzuhlcke@mozilla.com>
Mon, 11 Nov 2019 12:07:59 +0000
changeset 502403 9e0759e69df2c9b51bb7e2f26960f1f44d0a4274
parent 502402 71bcb50a0a8c3298af53e98cd741700f5c3392d2
child 502404 ce1b32236689a46bed461fe3ca79df58414394bc
push id114172
push userdluca@mozilla.com
push dateTue, 19 Nov 2019 11:31:10 +0000
treeherdermozilla-inbound@b5c5ba07d3db [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersvalentin
bugs1594613
milestone72.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1594613 - Added telemetry for http basic-auth confirm prompts and URI UserInfo usage. r=valentin Differential Revision: https://phabricator.services.mozilla.com/D52183
netwerk/protocol/http/nsHttpChannelAuthProvider.cpp
netwerk/protocol/http/nsHttpChannelAuthProvider.h
toolkit/components/telemetry/Histograms.json
--- a/netwerk/protocol/http/nsHttpChannelAuthProvider.cpp
+++ b/netwerk/protocol/http/nsHttpChannelAuthProvider.cpp
@@ -672,16 +672,17 @@ nsresult nsHttpChannelAuthProvider::GetC
     nsCOMPtr<nsIChannel> chan = do_QueryInterface(mAuthChannel);
     GetOriginAttributesSuffix(chan, suffix);
 
     // if this is the first challenge, then try using the identity
     // specified in the URL.
     if (mIdent.IsEmpty()) {
       GetIdentityFromURI(authFlags, mIdent);
       identFromURI = !mIdent.IsEmpty();
+      Telemetry::Accumulate(Telemetry::HTTP_AUTH_USERINFO_URI, identFromURI);
     }
 
     if ((loadFlags & nsIRequest::LOAD_ANONYMOUS) && !identFromURI) {
       LOG(("Skipping authentication for anonymous non-proxy request\n"));
       return NS_ERROR_NOT_AVAILABLE;
     }
 
     // Let explicit URL credentials pass
@@ -1421,42 +1422,54 @@ nsresult nsHttpChannelAuthProvider::Cont
   // authentication it'll respond with failure and resend the challenge list
   mRemainingChallenges.Truncate();
 
   Unused << mAuthChannel->OnAuthAvailable();
 
   return NS_OK;
 }
 
+void nsHttpChannelAuthProvider::RecordConfirmAuthTelemetry(const char* aType) {
+  if (nsCRT::strcmp(aType, "SuperfluousAuth")) {
+    Telemetry::AccumulateCategorical(
+        Telemetry::LABELS_HTTP_AUTH_CONFIRM_PROMPT::Superfluous);
+  } else if (nsCRT::strcmp(aType, "AutomaticAuth")) {
+    Telemetry::AccumulateCategorical(
+        Telemetry::LABELS_HTTP_AUTH_CONFIRM_PROMPT::Automatic);
+  }
+}
+
 bool nsHttpChannelAuthProvider::ConfirmAuth(const char* bundleKey,
                                             bool doYesNoPrompt) {
   // skip prompting the user if
   //   1) prompts are disabled by pref
   //   2) we've already prompted the user
   //   3) we're not a toplevel channel
   //   4) the userpass length is less than the "phishy" threshold
 
-  if (!StaticPrefs::network_auth_confirmAuth_enabled()) {
-    return true;
-  }
-
   uint32_t loadFlags;
   nsresult rv = mAuthChannel->GetLoadFlags(&loadFlags);
   if (NS_FAILED(rv)) return true;
 
   if (mSuppressDefensiveAuth ||
       !(loadFlags & nsIChannel::LOAD_INITIAL_DOCUMENT_URI))
     return true;
 
   nsAutoCString userPass;
   rv = mURI->GetUserPass(userPass);
   if (NS_FAILED(rv) ||
       (userPass.Length() < gHttpHandler->PhishyUserPassLength()))
     return true;
 
+  if (!StaticPrefs::network_auth_confirmAuth_enabled()) {
+    // If it wasn't for the pref, we would have prompted, record telemetry
+    RecordConfirmAuthTelemetry(bundleKey);
+    return true;
+  }
+
   // we try to confirm by prompting the user.  if we cannot do so, then
   // assume the user said ok.  this is done to keep things working in
   // embedded builds, where the string bundle might not be present, etc.
 
   nsCOMPtr<nsIStringBundleService> bundleService =
       do_GetService(NS_STRINGBUNDLE_CONTRACTID);
   if (!bundleService) return true;
 
@@ -1533,16 +1546,18 @@ bool nsHttpChannelAuthProvider::ConfirmA
     if (NS_FAILED(rv)) return true;
 
     confirmed = choice == 0;
   } else {
     rv = prompt->Confirm(nullptr, msg.get(), &confirmed);
     if (NS_FAILED(rv)) return true;
   }
 
+  RecordConfirmAuthTelemetry(bundleKey);
+
   return confirmed;
 }
 
 void nsHttpChannelAuthProvider::SetAuthorizationHeader(
     nsHttpAuthCache* authCache, nsHttpAtom header, const char* scheme,
     const char* host, int32_t port, const char* path,
     nsHttpAuthIdentity& ident) {
   nsHttpAuthEntry* entry = nullptr;
--- a/netwerk/protocol/http/nsHttpChannelAuthProvider.h
+++ b/netwerk/protocol/http/nsHttpChannelAuthProvider.h
@@ -81,16 +81,17 @@ class nsHttpChannelAuthProvider final : 
                                                    nsIHttpAuthenticator* auth,
                                                    nsCString& creds);
   MOZ_MUST_USE nsresult PromptForIdentity(uint32_t level, bool proxyAuth,
                                           const char* realm,
                                           const char* authType,
                                           uint32_t authFlags,
                                           nsHttpAuthIdentity&);
 
+  void RecordConfirmAuthTelemetry(const char* aType);
   bool ConfirmAuth(const char* bundleKey, bool doYesNoPrompt);
   void SetAuthorizationHeader(nsHttpAuthCache*, nsHttpAtom header,
                               const char* scheme, const char* host,
                               int32_t port, const char* path,
                               nsHttpAuthIdentity& ident);
   MOZ_MUST_USE nsresult GetCurrentPath(nsACString&);
   /**
    * Return all information needed to build authorization information,
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -2496,16 +2496,37 @@
     "alert_emails": ["rbarnes@mozilla.com"],
     "bug_numbers": [1266571],
     "expires_in_version": "52",
     "kind": "enumerated",
     "n_values": 8,
     "releaseChannelCollection": "opt-out",
     "description": "Recorded once for each HTTP 401 response. The value records the type of authentication and the TLS-enabled status. (0=basic/clear, 1=basic/tls, 2=digest/clear, 3=digest/tls, 4=ntlm/clear, 5=ntlm/tls, 6=negotiate/clear, 7=negotiate/tls)"
   },
+  "HTTP_AUTH_CONFIRM_PROMPT": {
+    "record_in_processes": ["main"],
+    "products": ["firefox", "geckoview"],
+    "alert_emails": ["seceng-telemetry@mozilla.com", "pbz@mozilla.com"],
+    "bug_numbers": [1594613],
+    "expires_in_version": "75",
+    "kind": "categorical",
+    "releaseChannelCollection": "opt-out",
+    "description": "Number of Automatic/Superfluous auth warning prompts shown. Prompts are counted even if disabled by pref.",
+    "labels": ["Automatic", "Superfluous"]
+  },
+  "HTTP_AUTH_USERINFO_URI": {
+    "record_in_processes": ["main"],
+    "products": ["firefox", "geckoview"],
+    "alert_emails": ["seceng-telemetry@mozilla.com", "pbz@mozilla.com"],
+    "bug_numbers": [1594613],
+    "expires_in_version": "75",
+    "kind": "boolean",
+    "releaseChannelCollection": "opt-out",
+    "description": "Counts http auth connections with (true) / without (false) userinfo in URI"
+  },
   "HTTP_CHILD_OMT_STATS": {
     "record_in_processes": ["content"],
     "products": ["firefox", "fennec", "geckoview"],
     "alert_emails": ["necko@mozilla.com"],
     "bug_numbers": [1357682],
     "expires_in_version": "61",
     "kind": "categorical",
     "keyed": true,