Commit a250ccfb authored by bhanudev's avatar bhanudev Committed by Commit bot

New SSL metric added: Likely From Same Domain

This metric records the CERT_COMMON_NAME_INVALID errors when the hostname entered and one of the dns names of the certificate have same effective domain name (eTLD+1).This helps us see if the certificate is completely random or if it is related to the current hostname.

BUG=507715

Review URL: https://codereview.chromium.org/1227173006

Cr-Commit-Position: refs/heads/master@{#339699}
parent 73e2f915
...@@ -55,6 +55,7 @@ enum SSLInterstitialCause { ...@@ -55,6 +55,7 @@ enum SSLInterstitialCause {
AUTHORITY_ERROR_CAPTIVE_PORTAL, AUTHORITY_ERROR_CAPTIVE_PORTAL,
SELF_SIGNED, SELF_SIGNED,
EXPIRED_RECENTLY, EXPIRED_RECENTLY,
LIKELY_SAME_DOMAIN,
UNUSED_INTERSTITIAL_CAUSE_ENTRY, UNUSED_INTERSTITIAL_CAUSE_ENTRY,
}; };
...@@ -208,6 +209,8 @@ void SSLErrorClassification::RecordUMAStatistics( ...@@ -208,6 +209,8 @@ void SSLErrorClassification::RecordUMAStatistics(
RecordSSLInterstitialCause(overridable, SUBDOMAIN_INVERSE_MATCH); RecordSSLInterstitialCause(overridable, SUBDOMAIN_INVERSE_MATCH);
if (IsCertLikelyFromMultiTenantHosting()) if (IsCertLikelyFromMultiTenantHosting())
RecordSSLInterstitialCause(overridable, LIKELY_MULTI_TENANT_HOSTING); RecordSSLInterstitialCause(overridable, LIKELY_MULTI_TENANT_HOSTING);
if (IsCertLikelyFromSameDomain())
RecordSSLInterstitialCause(overridable, LIKELY_SAME_DOMAIN);
} else { } else {
RecordSSLInterstitialCause(overridable, HOST_NAME_NOT_KNOWN_TLD); RecordSSLInterstitialCause(overridable, HOST_NAME_NOT_KNOWN_TLD);
} }
...@@ -463,6 +466,29 @@ bool SSLErrorClassification::IsCertLikelyFromMultiTenantHosting() const { ...@@ -463,6 +466,29 @@ bool SSLErrorClassification::IsCertLikelyFromMultiTenantHosting() const {
return true; return true;
} }
bool SSLErrorClassification::IsCertLikelyFromSameDomain() const {
std::string host_name = request_url_.host();
std::vector<std::string> dns_names;
cert_.GetDNSNames(&dns_names);
dns_names.push_back(host_name);
std::vector<std::string> dns_names_domain;
for (const std::string& dns_name : dns_names) {
dns_names_domain.push_back(
net::registry_controlled_domains::GetDomainAndRegistry(
dns_name,
net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES));
}
DCHECK(!dns_names_domain.empty());
const std::string& host_name_domain = dns_names_domain.back();
// Last element is the original domain. So, excluding it.
return std::find(dns_names_domain.begin(), dns_names_domain.end() - 1,
host_name_domain) != dns_names_domain.end() - 1;
}
// static // static
bool SSLErrorClassification::IsHostnameNonUniqueOrDotless( bool SSLErrorClassification::IsHostnameNonUniqueOrDotless(
const std::string& hostname) { const std::string& hostname) {
......
...@@ -117,6 +117,11 @@ class SSLErrorClassification : public content::NotificationObserver { ...@@ -117,6 +117,11 @@ class SSLErrorClassification : public content::NotificationObserver {
// fields. // fields.
bool IsCertLikelyFromMultiTenantHosting() const; bool IsCertLikelyFromMultiTenantHosting() const;
// Returns true if the hostname in |request_url_| has the same domain
// (effective TLD + 1 label) as at least one of the subject
// alternative names in |cert_|.
bool IsCertLikelyFromSameDomain() const;
static std::vector<Tokens> GetTokenizedDNSNames( static std::vector<Tokens> GetTokenizedDNSNames(
const std::vector<std::string>& dns_names); const std::vector<std::string>& dns_names);
......
...@@ -59,6 +59,7 @@ TEST_F(SSLErrorClassificationTest, TestNameMismatch) { ...@@ -59,6 +59,7 @@ TEST_F(SSLErrorClassificationTest, TestNameMismatch) {
host_name_tokens)); host_name_tokens));
EXPECT_FALSE(ssl_error.IsSubDomainOutsideWildcard(host_name_tokens)); EXPECT_FALSE(ssl_error.IsSubDomainOutsideWildcard(host_name_tokens));
EXPECT_FALSE(ssl_error.IsCertLikelyFromMultiTenantHosting()); EXPECT_FALSE(ssl_error.IsCertLikelyFromMultiTenantHosting());
EXPECT_TRUE(ssl_error.IsCertLikelyFromSameDomain());
} }
{ {
...@@ -76,6 +77,7 @@ TEST_F(SSLErrorClassificationTest, TestNameMismatch) { ...@@ -76,6 +77,7 @@ TEST_F(SSLErrorClassificationTest, TestNameMismatch) {
dns_name_tokens_google)); dns_name_tokens_google));
EXPECT_FALSE(ssl_error.AnyNamesUnderName(dns_name_tokens_google, EXPECT_FALSE(ssl_error.AnyNamesUnderName(dns_name_tokens_google,
host_name_tokens)); host_name_tokens));
EXPECT_TRUE(ssl_error.IsCertLikelyFromSameDomain());
} }
{ {
...@@ -93,6 +95,7 @@ TEST_F(SSLErrorClassificationTest, TestNameMismatch) { ...@@ -93,6 +95,7 @@ TEST_F(SSLErrorClassificationTest, TestNameMismatch) {
dns_name_tokens_google)); dns_name_tokens_google));
EXPECT_FALSE(ssl_error.AnyNamesUnderName(dns_name_tokens_google, EXPECT_FALSE(ssl_error.AnyNamesUnderName(dns_name_tokens_google,
host_name_tokens)); host_name_tokens));
EXPECT_TRUE(ssl_error.IsCertLikelyFromSameDomain());
} }
{ {
...@@ -110,6 +113,7 @@ TEST_F(SSLErrorClassificationTest, TestNameMismatch) { ...@@ -110,6 +113,7 @@ TEST_F(SSLErrorClassificationTest, TestNameMismatch) {
dns_name_tokens_google)); dns_name_tokens_google));
EXPECT_FALSE(ssl_error.AnyNamesUnderName(dns_name_tokens_google, EXPECT_FALSE(ssl_error.AnyNamesUnderName(dns_name_tokens_google,
host_name_tokens)); host_name_tokens));
EXPECT_FALSE(ssl_error.IsCertLikelyFromSameDomain());
} }
{ {
...@@ -127,6 +131,7 @@ TEST_F(SSLErrorClassificationTest, TestNameMismatch) { ...@@ -127,6 +131,7 @@ TEST_F(SSLErrorClassificationTest, TestNameMismatch) {
dns_name_tokens_google)); dns_name_tokens_google));
EXPECT_FALSE(ssl_error.AnyNamesUnderName(dns_name_tokens_google, EXPECT_FALSE(ssl_error.AnyNamesUnderName(dns_name_tokens_google,
host_name_tokens)); host_name_tokens));
EXPECT_FALSE(ssl_error.IsCertLikelyFromSameDomain());
} }
scoped_refptr<net::X509Certificate> webkit_cert( scoped_refptr<net::X509Certificate> webkit_cert(
...@@ -155,6 +160,7 @@ TEST_F(SSLErrorClassificationTest, TestNameMismatch) { ...@@ -155,6 +160,7 @@ TEST_F(SSLErrorClassificationTest, TestNameMismatch) {
host_name_tokens)); host_name_tokens));
EXPECT_TRUE(ssl_error.IsSubDomainOutsideWildcard(host_name_tokens)); EXPECT_TRUE(ssl_error.IsSubDomainOutsideWildcard(host_name_tokens));
EXPECT_FALSE(ssl_error.IsCertLikelyFromMultiTenantHosting()); EXPECT_FALSE(ssl_error.IsCertLikelyFromMultiTenantHosting());
EXPECT_TRUE(ssl_error.IsCertLikelyFromSameDomain());
} }
} }
......
...@@ -68907,6 +68907,13 @@ To add a new entry, add it with any value and run test to compute valid value. ...@@ -68907,6 +68907,13 @@ To add a new entry, add it with any value and run test to compute valid value.
<int value="12" label="EXPIRED_RECENTLY: Cert expired within last 28 days."> <int value="12" label="EXPIRED_RECENTLY: Cert expired within last 28 days.">
</int> </int>
<int value="13"
label="LIKELY_SAME_DOMAIN: Cert likely belongs to the same domain">
This case is recorded if the SSL error is CERT_COMMON_NAME_INVALID error and
the hostname in request URL has the same domain (effective TLD + 1 label) as
the common name or at least one of the subject alternative names in
certificate. This case is not recorded if the host name is not a known tld.
</int>
</enum> </enum>
<enum name="SSLErrorHandlerEvent" type="int"> <enum name="SSLErrorHandlerEvent" type="int">
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment