| // Copyright 2015 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "components/security_state/core/security_state.h" |
| |
| #include <stdint.h> |
| #include <memory> |
| #include <utility> |
| |
| #include "base/bind.h" |
| #include "base/command_line.h" |
| #include "base/test/metrics/histogram_tester.h" |
| #include "base/test/scoped_feature_list.h" |
| #include "components/security_state/core/features.h" |
| #include "components/security_state/core/insecure_input_event_data.h" |
| #include "net/cert/x509_certificate.h" |
| #include "net/ssl/ssl_cipher_suite_names.h" |
| #include "net/ssl/ssl_connection_status_flags.h" |
| #include "net/test/cert_test_util.h" |
| #include "net/test/test_certificate_data.h" |
| #include "net/test/test_data_directory.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace security_state { |
| |
| namespace { |
| |
| const char kHttpsUrl[] = "https://foo.test/"; |
| const char kHttpUrl[] = "http://foo.test/"; |
| const char kLocalhostUrl[] = "http://localhost"; |
| const char kFileOrigin[] = "file://example_file"; |
| const char kWssUrl[] = "wss://foo.test/"; |
| |
| // This list doesn't include data: URL, as data: URLs will be explicitly marked |
| // as not secure. |
| const char* const kPseudoUrls[] = { |
| "blob:http://test/some-guid", "filesystem:http://test/some-guid", |
| }; |
| |
| bool IsOriginSecure(const GURL& url) { |
| return url == kHttpsUrl; |
| } |
| |
| class TestSecurityStateHelper { |
| public: |
| TestSecurityStateHelper() |
| : url_(kHttpsUrl), |
| cert_(net::ImportCertFromFile(net::GetTestCertsDirectory(), |
| "sha1_2016.pem")), |
| connection_status_(net::SSL_CONNECTION_VERSION_TLS1_2 |
| << net::SSL_CONNECTION_VERSION_SHIFT), |
| cert_status_(net::CERT_STATUS_SHA1_SIGNATURE_PRESENT), |
| displayed_mixed_content_(false), |
| contained_mixed_form_(false), |
| ran_mixed_content_(false), |
| malicious_content_status_(MALICIOUS_CONTENT_STATUS_NONE), |
| is_incognito_(false), |
| is_error_page_(false), |
| is_view_source_(false), |
| has_policy_certificate_(false) {} |
| virtual ~TestSecurityStateHelper() {} |
| |
| void SetCertificate(scoped_refptr<net::X509Certificate> cert) { |
| cert_ = std::move(cert); |
| } |
| void set_connection_status(int connection_status) { |
| connection_status_ = connection_status; |
| } |
| void SetCipherSuite(uint16_t ciphersuite) { |
| net::SSLConnectionStatusSetCipherSuite(ciphersuite, &connection_status_); |
| } |
| void AddCertStatus(net::CertStatus cert_status) { |
| cert_status_ |= cert_status; |
| } |
| void set_cert_status(net::CertStatus cert_status) { |
| cert_status_ = cert_status; |
| } |
| void set_displayed_mixed_content(bool displayed_mixed_content) { |
| displayed_mixed_content_ = displayed_mixed_content; |
| } |
| void set_contained_mixed_form(bool contained_mixed_form) { |
| contained_mixed_form_ = contained_mixed_form; |
| } |
| void set_ran_mixed_content(bool ran_mixed_content) { |
| ran_mixed_content_ = ran_mixed_content; |
| } |
| void set_malicious_content_status( |
| MaliciousContentStatus malicious_content_status) { |
| malicious_content_status_ = malicious_content_status; |
| } |
| void set_password_field_shown(bool password_field_shown) { |
| insecure_input_events_.password_field_shown = password_field_shown; |
| } |
| void set_credit_card_field_edited(bool credit_card_field_edited) { |
| insecure_input_events_.credit_card_field_edited = credit_card_field_edited; |
| } |
| void set_is_incognito(bool is_incognito) { is_incognito_ = is_incognito; } |
| |
| void set_is_error_page(bool is_error_page) { is_error_page_ = is_error_page; } |
| |
| void set_is_view_source(bool is_view_source) { |
| is_view_source_ = is_view_source; |
| } |
| |
| void set_insecure_field_edit(bool insecure_field_edit) { |
| insecure_input_events_.insecure_field_edited = insecure_field_edit; |
| } |
| void set_has_policy_certificate(bool has_policy_cert) { |
| has_policy_certificate_ = has_policy_cert; |
| } |
| void SetUrl(const GURL& url) { url_ = url; } |
| |
| std::unique_ptr<VisibleSecurityState> GetVisibleSecurityState() const { |
| auto state = std::make_unique<VisibleSecurityState>(); |
| state->connection_info_initialized = true; |
| state->url = url_; |
| state->certificate = cert_; |
| state->cert_status = cert_status_; |
| state->connection_status = connection_status_; |
| state->security_bits = 256; |
| state->displayed_mixed_content = displayed_mixed_content_; |
| state->contained_mixed_form = contained_mixed_form_; |
| state->ran_mixed_content = ran_mixed_content_; |
| state->malicious_content_status = malicious_content_status_; |
| state->is_incognito = is_incognito_; |
| state->is_error_page = is_error_page_; |
| state->is_view_source = is_view_source_; |
| state->insecure_input_events = insecure_input_events_; |
| return state; |
| } |
| |
| void GetSecurityInfo(SecurityInfo* security_info) const { |
| security_state::GetSecurityInfo(GetVisibleSecurityState(), |
| has_policy_certificate_, |
| base::Bind(&IsOriginSecure), security_info); |
| } |
| |
| private: |
| GURL url_; |
| scoped_refptr<net::X509Certificate> cert_; |
| int connection_status_; |
| net::CertStatus cert_status_; |
| bool displayed_mixed_content_; |
| bool contained_mixed_form_; |
| bool ran_mixed_content_; |
| MaliciousContentStatus malicious_content_status_; |
| bool is_incognito_; |
| bool is_error_page_; |
| bool is_view_source_; |
| bool has_policy_certificate_; |
| InsecureInputEventData insecure_input_events_; |
| }; |
| |
| } // namespace |
| |
| // Tests that SHA1-signed certificates, when not allowed by policy, downgrade |
| // the security state of the page to DANGEROUS. |
| TEST(SecurityStateTest, SHA1Blocked) { |
| TestSecurityStateHelper helper; |
| helper.AddCertStatus(net::CERT_STATUS_WEAK_SIGNATURE_ALGORITHM); |
| helper.AddCertStatus(net::CERT_STATUS_SHA1_SIGNATURE_PRESENT); |
| SecurityInfo security_info; |
| helper.GetSecurityInfo(&security_info); |
| EXPECT_TRUE(security_info.sha1_in_chain); |
| EXPECT_EQ(DANGEROUS, security_info.security_level); |
| |
| // Ensure that policy-installed certificates do not interfere. |
| helper.set_has_policy_certificate(true); |
| SecurityInfo policy_cert_security_info; |
| helper.GetSecurityInfo(&policy_cert_security_info); |
| EXPECT_TRUE(policy_cert_security_info.sha1_in_chain); |
| EXPECT_EQ(DANGEROUS, policy_cert_security_info.security_level); |
| } |
| |
| // Tests that SHA1-signed certificates, when allowed by policy, downgrade the |
| // security state of the page to NONE. |
| TEST(SecurityStateTest, SHA1Warning) { |
| TestSecurityStateHelper helper; |
| SecurityInfo security_info; |
| helper.GetSecurityInfo(&security_info); |
| EXPECT_TRUE(security_info.sha1_in_chain); |
| EXPECT_EQ(NONE, security_info.security_level); |
| |
| // Ensure that policy-installed certificates do not interfere. |
| helper.set_has_policy_certificate(true); |
| SecurityInfo policy_cert_security_info; |
| helper.GetSecurityInfo(&policy_cert_security_info); |
| EXPECT_TRUE(policy_cert_security_info.sha1_in_chain); |
| EXPECT_EQ(NONE, policy_cert_security_info.security_level); |
| } |
| |
| // Tests that SHA1-signed certificates, when allowed by policy, don't interfere |
| // with the handling of mixed content. |
| TEST(SecurityStateTest, SHA1WarningMixedContent) { |
| TestSecurityStateHelper helper; |
| helper.set_displayed_mixed_content(true); |
| SecurityInfo security_info1; |
| helper.GetSecurityInfo(&security_info1); |
| EXPECT_TRUE(security_info1.sha1_in_chain); |
| EXPECT_EQ(CONTENT_STATUS_DISPLAYED, security_info1.mixed_content_status); |
| EXPECT_EQ(NONE, security_info1.security_level); |
| |
| helper.set_displayed_mixed_content(false); |
| helper.set_ran_mixed_content(true); |
| SecurityInfo security_info2; |
| helper.GetSecurityInfo(&security_info2); |
| EXPECT_TRUE(security_info2.sha1_in_chain); |
| EXPECT_EQ(CONTENT_STATUS_RAN, security_info2.mixed_content_status); |
| EXPECT_EQ(DANGEROUS, security_info2.security_level); |
| } |
| |
| // Tests that SHA1-signed certificates, when allowed by policy, |
| // don't interfere with the handling of major cert errors. |
| TEST(SecurityStateTest, SHA1WarningBrokenHTTPS) { |
| TestSecurityStateHelper helper; |
| helper.AddCertStatus(net::CERT_STATUS_DATE_INVALID); |
| SecurityInfo security_info; |
| helper.GetSecurityInfo(&security_info); |
| EXPECT_TRUE(security_info.sha1_in_chain); |
| EXPECT_EQ(DANGEROUS, security_info.security_level); |
| } |
| |
| // Tests that |security_info.is_secure_protocol_and_ciphersuite| is |
| // computed correctly. |
| TEST(SecurityStateTest, SecureProtocolAndCiphersuite) { |
| TestSecurityStateHelper helper; |
| // TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 from |
| // http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-4 |
| const uint16_t ciphersuite = 0xc02f; |
| helper.set_connection_status(net::SSL_CONNECTION_VERSION_TLS1_2 |
| << net::SSL_CONNECTION_VERSION_SHIFT); |
| helper.SetCipherSuite(ciphersuite); |
| SecurityInfo security_info; |
| helper.GetSecurityInfo(&security_info); |
| EXPECT_EQ(net::OBSOLETE_SSL_NONE, security_info.obsolete_ssl_status); |
| } |
| |
| TEST(SecurityStateTest, NonsecureProtocol) { |
| TestSecurityStateHelper helper; |
| // TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 from |
| // http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-4 |
| const uint16_t ciphersuite = 0xc02f; |
| helper.set_connection_status(net::SSL_CONNECTION_VERSION_TLS1_1 |
| << net::SSL_CONNECTION_VERSION_SHIFT); |
| helper.SetCipherSuite(ciphersuite); |
| SecurityInfo security_info; |
| helper.GetSecurityInfo(&security_info); |
| EXPECT_EQ(net::OBSOLETE_SSL_MASK_PROTOCOL, security_info.obsolete_ssl_status); |
| } |
| |
| TEST(SecurityStateTest, NonsecureCiphersuite) { |
| TestSecurityStateHelper helper; |
| // TLS_RSA_WITH_AES_128_CCM_8 from |
| // http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-4 |
| const uint16_t ciphersuite = 0xc0a0; |
| helper.set_connection_status(net::SSL_CONNECTION_VERSION_TLS1_2 |
| << net::SSL_CONNECTION_VERSION_SHIFT); |
| helper.SetCipherSuite(ciphersuite); |
| SecurityInfo security_info; |
| helper.GetSecurityInfo(&security_info); |
| EXPECT_EQ(net::OBSOLETE_SSL_MASK_KEY_EXCHANGE | net::OBSOLETE_SSL_MASK_CIPHER, |
| security_info.obsolete_ssl_status); |
| } |
| |
| // Tests that the malware/phishing status is set, and it overrides valid HTTPS. |
| TEST(SecurityStateTest, MalwareOverride) { |
| TestSecurityStateHelper helper; |
| // TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 from |
| // http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-4 |
| const uint16_t ciphersuite = 0xc02f; |
| helper.set_connection_status(net::SSL_CONNECTION_VERSION_TLS1_2 |
| << net::SSL_CONNECTION_VERSION_SHIFT); |
| helper.SetCipherSuite(ciphersuite); |
| |
| SecurityInfo security_info; |
| helper.GetSecurityInfo(&security_info); |
| EXPECT_EQ(MALICIOUS_CONTENT_STATUS_NONE, |
| security_info.malicious_content_status); |
| |
| helper.set_malicious_content_status(MALICIOUS_CONTENT_STATUS_MALWARE); |
| helper.GetSecurityInfo(&security_info); |
| |
| EXPECT_EQ(MALICIOUS_CONTENT_STATUS_MALWARE, |
| security_info.malicious_content_status); |
| EXPECT_EQ(DANGEROUS, security_info.security_level); |
| } |
| |
| // Tests that the malware/phishing status is set, even if other connection info |
| // is not available. |
| TEST(SecurityStateTest, MalwareWithoutConnectionState) { |
| TestSecurityStateHelper helper; |
| helper.set_malicious_content_status( |
| MALICIOUS_CONTENT_STATUS_SOCIAL_ENGINEERING); |
| SecurityInfo security_info; |
| helper.GetSecurityInfo(&security_info); |
| EXPECT_EQ(MALICIOUS_CONTENT_STATUS_SOCIAL_ENGINEERING, |
| security_info.malicious_content_status); |
| EXPECT_EQ(DANGEROUS, security_info.security_level); |
| } |
| |
| // Tests that pseudo URLs always cause an HTTP_SHOW_WARNING to be shown, |
| // regardless of whether a password or credit card field was displayed. |
| TEST(SecurityStateTest, AlwaysWarnOnDataUrls) { |
| TestSecurityStateHelper helper; |
| helper.SetUrl(GURL("data:text/html,<html>test</html>")); |
| helper.set_password_field_shown(false); |
| helper.set_credit_card_field_edited(false); |
| SecurityInfo security_info; |
| helper.GetSecurityInfo(&security_info); |
| EXPECT_FALSE(security_info.insecure_input_events.password_field_shown); |
| EXPECT_FALSE(security_info.insecure_input_events.credit_card_field_edited); |
| EXPECT_EQ(HTTP_SHOW_WARNING, security_info.security_level); |
| } |
| |
| // Tests that FTP URLs always cause an HTTP_SHOW_WARNING to be shown, |
| // regardless of whether a password or credit card field was displayed. |
| TEST(SecurityStateTest, AlwaysWarnOnFtpUrls) { |
| TestSecurityStateHelper helper; |
| helper.SetUrl(GURL("ftp://example.test/")); |
| helper.set_password_field_shown(false); |
| helper.set_credit_card_field_edited(false); |
| SecurityInfo security_info; |
| helper.GetSecurityInfo(&security_info); |
| EXPECT_FALSE(security_info.insecure_input_events.password_field_shown); |
| EXPECT_FALSE(security_info.insecure_input_events.credit_card_field_edited); |
| EXPECT_EQ(HTTP_SHOW_WARNING, security_info.security_level); |
| } |
| |
| // Tests that password fields cause the security level to be downgraded |
| // to HTTP_SHOW_WARNING. |
| TEST(SecurityStateTest, PasswordFieldWarning) { |
| TestSecurityStateHelper helper; |
| helper.SetUrl(GURL(kHttpUrl)); |
| helper.set_password_field_shown(true); |
| SecurityInfo security_info; |
| helper.GetSecurityInfo(&security_info); |
| EXPECT_TRUE(security_info.insecure_input_events.password_field_shown); |
| EXPECT_EQ(HTTP_SHOW_WARNING, security_info.security_level); |
| } |
| |
| // Tests that the security level is downgraded to HTTP_SHOW_WARNING on pseudo |
| // URLs. |
| TEST(SecurityStateTest, WarningOnPseudoUrls) { |
| for (const char* const url : kPseudoUrls) { |
| TestSecurityStateHelper helper; |
| helper.SetUrl(GURL(url)); |
| SecurityInfo security_info; |
| helper.GetSecurityInfo(&security_info); |
| EXPECT_EQ(HTTP_SHOW_WARNING, security_info.security_level); |
| } |
| } |
| |
| // Tests that credit card fields cause the security level to be downgraded |
| // to HTTP_SHOW_WARNING. |
| TEST(SecurityStateTest, CreditCardFieldWarning) { |
| TestSecurityStateHelper helper; |
| helper.SetUrl(GURL(kHttpUrl)); |
| helper.set_credit_card_field_edited(true); |
| SecurityInfo security_info; |
| helper.GetSecurityInfo(&security_info); |
| EXPECT_TRUE(security_info.insecure_input_events.credit_card_field_edited); |
| EXPECT_EQ(HTTP_SHOW_WARNING, security_info.security_level); |
| } |
| |
| // Tests that neither |password_field_shown| nor |
| // |credit_card_field_edited| is set when the corresponding |
| // VisibleSecurityState flags are not set. |
| TEST(SecurityStateTest, PrivateUserDataNotSet) { |
| TestSecurityStateHelper helper; |
| helper.SetUrl(GURL(kHttpUrl)); |
| SecurityInfo security_info; |
| helper.GetSecurityInfo(&security_info); |
| EXPECT_FALSE(security_info.insecure_input_events.password_field_shown); |
| EXPECT_FALSE(security_info.insecure_input_events.credit_card_field_edited); |
| EXPECT_EQ(HTTP_SHOW_WARNING, security_info.security_level); |
| } |
| |
| // Tests that neither |password_field_shown| nor |
| // |credit_card_field_edited| is set on pseudo URLs when the |
| // corresponding VisibleSecurityState flags are not set. |
| TEST(SecurityStateTest, PrivateUserDataNotSetOnPseudoUrls) { |
| for (const char* const url : kPseudoUrls) { |
| TestSecurityStateHelper helper; |
| helper.SetUrl(GURL(url)); |
| SecurityInfo security_info; |
| helper.GetSecurityInfo(&security_info); |
| EXPECT_FALSE(security_info.insecure_input_events.password_field_shown); |
| EXPECT_FALSE(security_info.insecure_input_events.credit_card_field_edited); |
| EXPECT_EQ(HTTP_SHOW_WARNING, security_info.security_level); |
| } |
| } |
| |
| // Tests that if |is_view_source| NONE is returned for a secure site. |
| TEST(SecurityStateTest, ViewSourceRemovesSecure) { |
| TestSecurityStateHelper helper; |
| SecurityInfo security_info; |
| helper.set_cert_status(0); |
| helper.GetSecurityInfo(&security_info); |
| EXPECT_EQ(SECURE, security_info.security_level); |
| helper.set_is_view_source(true); |
| helper.GetSecurityInfo(&security_info); |
| EXPECT_EQ(NONE, security_info.security_level); |
| } |
| |
| // Tests that if |is_view_source|, DANGEROUS is still returned for a site |
| // flagged by SafeBrowsing. |
| TEST(SecurityStateTest, ViewSourceKeepsWarning) { |
| TestSecurityStateHelper helper; |
| helper.set_malicious_content_status( |
| MALICIOUS_CONTENT_STATUS_SOCIAL_ENGINEERING); |
| helper.set_is_view_source(true); |
| SecurityInfo security_info; |
| helper.GetSecurityInfo(&security_info); |
| EXPECT_EQ(MALICIOUS_CONTENT_STATUS_SOCIAL_ENGINEERING, |
| security_info.malicious_content_status); |
| EXPECT_EQ(DANGEROUS, security_info.security_level); |
| } |
| |
| // Tests that |incognito_downgraded_security_level| is set only when the |
| // corresponding VisibleSecurityState flag is set. The incognito downgrade is |
| // only performed when the HTTP-Bad feature is disabled. |
| TEST(SecurityStateTest, IncognitoFlagPropagates) { |
| TestSecurityStateHelper helper; |
| helper.SetUrl(GURL(kHttpUrl)); |
| SecurityInfo security_info; |
| |
| { |
| // When the feature is disabled, the downgraded flag should be set for |
| // incognito http pages. |
| base::test::ScopedFeatureList scoped_feature_list; |
| scoped_feature_list.InitAndDisableFeature( |
| security_state::features::kMarkHttpAsFeature); |
| helper.set_is_incognito(false); |
| helper.GetSecurityInfo(&security_info); |
| EXPECT_FALSE(security_info.incognito_downgraded_security_level); |
| |
| helper.set_is_incognito(true); |
| helper.GetSecurityInfo(&security_info); |
| EXPECT_TRUE(security_info.incognito_downgraded_security_level); |
| } |
| |
| { |
| // When the feature is enabled, the downgraded flag should never be set. |
| base::test::ScopedFeatureList scoped_feature_list; |
| scoped_feature_list.InitAndEnableFeature( |
| security_state::features::kMarkHttpAsFeature); |
| helper.set_is_incognito(false); |
| helper.GetSecurityInfo(&security_info); |
| EXPECT_FALSE(security_info.incognito_downgraded_security_level); |
| |
| helper.set_is_incognito(true); |
| helper.GetSecurityInfo(&security_info); |
| EXPECT_FALSE(security_info.incognito_downgraded_security_level); |
| } |
| } |
| |
| TEST(SecurityStateTest, DetectSubjectAltName) { |
| TestSecurityStateHelper helper; |
| |
| // Ensure subjectAltName is detected as present when the cert includes it. |
| SecurityInfo san_security_info; |
| helper.GetSecurityInfo(&san_security_info); |
| EXPECT_FALSE(san_security_info.cert_missing_subject_alt_name); |
| |
| // Ensure subjectAltName is detected as missing when the cert doesn't |
| // include it. |
| scoped_refptr<net::X509Certificate> cert = net::ImportCertFromFile( |
| net::GetTestCertsDirectory(), "salesforce_com_test.pem"); |
| ASSERT_TRUE(cert); |
| helper.SetCertificate(std::move(cert)); |
| |
| SecurityInfo no_san_security_info; |
| helper.GetSecurityInfo(&no_san_security_info); |
| EXPECT_TRUE(no_san_security_info.cert_missing_subject_alt_name); |
| } |
| |
| // Tests that a mixed form is reflected in the SecurityInfo. |
| TEST(SecurityStateTest, MixedForm) { |
| TestSecurityStateHelper helper; |
| |
| SecurityInfo no_mixed_form_security_info; |
| helper.GetSecurityInfo(&no_mixed_form_security_info); |
| EXPECT_FALSE(no_mixed_form_security_info.contained_mixed_form); |
| |
| helper.set_contained_mixed_form(true); |
| |
| // Verify that a mixed form downgrades the security level. |
| SecurityInfo mixed_form_security_info; |
| helper.GetSecurityInfo(&mixed_form_security_info); |
| EXPECT_TRUE(mixed_form_security_info.contained_mixed_form); |
| EXPECT_EQ(CONTENT_STATUS_NONE, mixed_form_security_info.mixed_content_status); |
| EXPECT_EQ(NONE, mixed_form_security_info.security_level); |
| |
| // Ensure that active mixed content trumps the mixed form warning. |
| helper.set_ran_mixed_content(true); |
| SecurityInfo mixed_form_and_active_security_info; |
| helper.GetSecurityInfo(&mixed_form_and_active_security_info); |
| EXPECT_TRUE(mixed_form_and_active_security_info.contained_mixed_form); |
| EXPECT_EQ(CONTENT_STATUS_RAN, |
| mixed_form_and_active_security_info.mixed_content_status); |
| EXPECT_EQ(DANGEROUS, mixed_form_and_active_security_info.security_level); |
| } |
| |
| // Tests that policy-installed-certificates do not interfere with mixed content |
| // notifications. |
| TEST(SecurityStateTest, MixedContentWithPolicyCertificate) { |
| TestSecurityStateHelper helper; |
| |
| helper.set_has_policy_certificate(true); |
| helper.set_cert_status(0); |
| |
| { |
| // Verify that if no mixed content is present, the policy-installed |
| // certificate is recorded. |
| SecurityInfo no_mixed_content_security_info; |
| helper.GetSecurityInfo(&no_mixed_content_security_info); |
| EXPECT_FALSE(no_mixed_content_security_info.contained_mixed_form); |
| EXPECT_EQ(CONTENT_STATUS_NONE, |
| no_mixed_content_security_info.mixed_content_status); |
| EXPECT_EQ(SECURE_WITH_POLICY_INSTALLED_CERT, |
| no_mixed_content_security_info.security_level); |
| } |
| |
| { |
| // Verify that a mixed form downgrades the security level. |
| SecurityInfo mixed_form_security_info; |
| helper.set_contained_mixed_form(true); |
| helper.GetSecurityInfo(&mixed_form_security_info); |
| EXPECT_TRUE(mixed_form_security_info.contained_mixed_form); |
| EXPECT_EQ(CONTENT_STATUS_NONE, |
| mixed_form_security_info.mixed_content_status); |
| EXPECT_EQ(NONE, mixed_form_security_info.security_level); |
| } |
| |
| { |
| // Verify that passive mixed content downgrades the security level. |
| helper.set_contained_mixed_form(false); |
| helper.set_displayed_mixed_content(true); |
| SecurityInfo passive_mixed_security_info; |
| helper.GetSecurityInfo(&passive_mixed_security_info); |
| EXPECT_EQ(CONTENT_STATUS_DISPLAYED, |
| passive_mixed_security_info.mixed_content_status); |
| EXPECT_EQ(NONE, passive_mixed_security_info.security_level); |
| } |
| |
| { |
| // Ensure that active mixed content downgrades the security level. |
| helper.set_contained_mixed_form(false); |
| helper.set_displayed_mixed_content(false); |
| helper.set_ran_mixed_content(true); |
| SecurityInfo active_mixed_security_info; |
| helper.GetSecurityInfo(&active_mixed_security_info); |
| EXPECT_EQ(CONTENT_STATUS_RAN, |
| active_mixed_security_info.mixed_content_status); |
| EXPECT_EQ(DANGEROUS, active_mixed_security_info.security_level); |
| } |
| } |
| |
| // Tests that a field edit is reflected in the SecurityInfo. |
| TEST(SecurityStateTest, FieldEdit) { |
| TestSecurityStateHelper helper; |
| helper.SetUrl(GURL(kHttpUrl)); |
| |
| { |
| // Test that a warning is shown on field edits, when the feature is |
| // disabled. |
| base::test::ScopedFeatureList scoped_feature_list; |
| scoped_feature_list.InitAndDisableFeature( |
| security_state::features::kMarkHttpAsFeature); |
| |
| SecurityInfo no_field_edit_security_info; |
| helper.GetSecurityInfo(&no_field_edit_security_info); |
| EXPECT_FALSE(no_field_edit_security_info.insecure_input_events |
| .insecure_field_edited); |
| EXPECT_FALSE( |
| no_field_edit_security_info.field_edit_downgraded_security_level); |
| EXPECT_EQ(NONE, no_field_edit_security_info.security_level); |
| |
| helper.set_insecure_field_edit(true); |
| |
| SecurityInfo security_info; |
| helper.GetSecurityInfo(&security_info); |
| EXPECT_TRUE(security_info.insecure_input_events.insecure_field_edited); |
| EXPECT_TRUE(security_info.field_edit_downgraded_security_level); |
| EXPECT_EQ(HTTP_SHOW_WARNING, security_info.security_level); |
| } |
| |
| { |
| // Test that the default enabled configuration shows the dangerous warning |
| // on field edits. |
| base::test::ScopedFeatureList scoped_feature_list; |
| scoped_feature_list.InitAndEnableFeature( |
| security_state::features::kMarkHttpAsFeature); |
| |
| SecurityInfo security_info; |
| helper.GetSecurityInfo(&security_info); |
| EXPECT_TRUE(security_info.insecure_input_events.insecure_field_edited); |
| EXPECT_FALSE(security_info.field_edit_downgraded_security_level); |
| EXPECT_EQ(DANGEROUS, security_info.security_level); |
| } |
| } |
| |
| // Tests IsSchemeCryptographic function. |
| TEST(SecurityStateTest, CryptographicSchemeUrl) { |
| // HTTPS is a cryptographic scheme. |
| EXPECT_TRUE(IsSchemeCryptographic(GURL(kHttpsUrl))); |
| // WSS is a cryptographic scheme. |
| EXPECT_TRUE(IsSchemeCryptographic(GURL(kWssUrl))); |
| // HTTP is not a cryptographic scheme. |
| EXPECT_FALSE(IsSchemeCryptographic(GURL(kHttpUrl))); |
| // Return true only for valid |url| |
| EXPECT_FALSE(IsSchemeCryptographic(GURL("https://"))); |
| } |
| |
| // Tests IsOriginLocalhostOrFile function. |
| TEST(SecurityStateTest, LocalhostOrFileUrl) { |
| EXPECT_TRUE(IsOriginLocalhostOrFile(GURL(kLocalhostUrl))); |
| EXPECT_TRUE(IsOriginLocalhostOrFile(GURL(kFileOrigin))); |
| EXPECT_FALSE(IsOriginLocalhostOrFile(GURL(kHttpsUrl))); |
| } |
| |
| // Tests IsSslCertificateValid function. |
| TEST(SecurityStateTest, SslCertificateValid) { |
| EXPECT_TRUE(IsSslCertificateValid(SecurityLevel::SECURE)); |
| EXPECT_TRUE(IsSslCertificateValid(SecurityLevel::EV_SECURE)); |
| EXPECT_TRUE( |
| IsSslCertificateValid(SecurityLevel::SECURE_WITH_POLICY_INSTALLED_CERT)); |
| |
| EXPECT_FALSE(IsSslCertificateValid(SecurityLevel::NONE)); |
| EXPECT_FALSE(IsSslCertificateValid(SecurityLevel::DANGEROUS)); |
| EXPECT_FALSE(IsSslCertificateValid(SecurityLevel::HTTP_SHOW_WARNING)); |
| } |
| |
| // Tests that HTTP_SHOW_WARNING is not set in incognito for error pages. |
| TEST(SecurityStateTest, IncognitoErrorPage) { |
| TestSecurityStateHelper helper; |
| SecurityInfo security_info; |
| helper.SetUrl(GURL("http://nonexistent.test")); |
| helper.set_is_incognito(true); |
| helper.set_is_error_page(true); |
| helper.GetSecurityInfo(&security_info); |
| EXPECT_EQ(SecurityLevel::NONE, security_info.security_level); |
| EXPECT_FALSE(security_info.incognito_downgraded_security_level); |
| |
| // Sanity-check that if it's not an error page, the security level is |
| // downgraded. |
| helper.set_is_error_page(false); |
| helper.GetSecurityInfo(&security_info); |
| EXPECT_EQ(SecurityLevel::HTTP_SHOW_WARNING, security_info.security_level); |
| } |
| |
| // Tests that HTTP_SHOW_WARNING is set on normal http pages but DANGEROUS on |
| // form edits when the default feature configuration is enabled. |
| TEST(SecurityStateTest, WarningAndDangerousOnFormEdits) { |
| base::test::ScopedFeatureList scoped_feature_list; |
| scoped_feature_list.InitAndEnableFeature( |
| security_state::features::kMarkHttpAsFeature); |
| |
| TestSecurityStateHelper helper; |
| helper.SetUrl(GURL(kHttpUrl)); |
| |
| { |
| SecurityInfo security_info; |
| helper.GetSecurityInfo(&security_info); |
| EXPECT_EQ(security_state::HTTP_SHOW_WARNING, security_info.security_level); |
| } |
| |
| { |
| SecurityInfo security_info; |
| helper.set_insecure_field_edit(true); |
| helper.GetSecurityInfo(&security_info); |
| EXPECT_EQ(security_state::DANGEROUS, security_info.security_level); |
| } |
| |
| { |
| SecurityInfo security_info; |
| helper.set_insecure_field_edit(false); |
| helper.set_password_field_shown(true); |
| helper.GetSecurityInfo(&security_info); |
| EXPECT_EQ(security_state::HTTP_SHOW_WARNING, security_info.security_level); |
| } |
| } |
| |
| // Tests that HTTP_SHOW_WARNING is set on normal http pages but DANGEROUS on |
| // sensitive fields when the |
| // 'warning-and-dangerous-on-passwords-and-credit-cards' field trial |
| // configuration is enabled. |
| TEST(SecurityStateTest, WarningAndDangerousOnSensitiveFields) { |
| base::test::ScopedFeatureList scoped_feature_list; |
| scoped_feature_list.InitAndEnableFeatureWithParameters( |
| security_state::features::kMarkHttpAsFeature, |
| {{security_state::features::kMarkHttpAsFeatureParameterName, |
| security_state::features:: |
| kMarkHttpAsParameterWarningAndDangerousOnPasswordsAndCreditCards}}); |
| |
| TestSecurityStateHelper helper; |
| helper.SetUrl(GURL(kHttpUrl)); |
| |
| { |
| SecurityInfo security_info; |
| helper.GetSecurityInfo(&security_info); |
| EXPECT_EQ(security_state::HTTP_SHOW_WARNING, security_info.security_level); |
| } |
| |
| { |
| SecurityInfo security_info; |
| helper.set_insecure_field_edit(true); |
| helper.GetSecurityInfo(&security_info); |
| EXPECT_EQ(security_state::HTTP_SHOW_WARNING, security_info.security_level); |
| } |
| |
| { |
| SecurityInfo security_info; |
| helper.set_insecure_field_edit(false); |
| helper.set_password_field_shown(true); |
| helper.GetSecurityInfo(&security_info); |
| EXPECT_EQ(security_state::DANGEROUS, security_info.security_level); |
| } |
| |
| { |
| SecurityInfo security_info; |
| helper.set_password_field_shown(false); |
| helper.set_credit_card_field_edited(true); |
| helper.GetSecurityInfo(&security_info); |
| EXPECT_EQ(security_state::DANGEROUS, security_info.security_level); |
| } |
| } |
| |
| } // namespace security_state |