Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(12)

Unified Diff: chrome/browser/ssl/ssl_browser_tests.cc

Issue 2865753003: Stop on redirects while checking for www mismatches (Closed)
Patch Set: Rebase Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/ssl/common_name_mismatch_handler.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/ssl/ssl_browser_tests.cc
diff --git a/chrome/browser/ssl/ssl_browser_tests.cc b/chrome/browser/ssl/ssl_browser_tests.cc
index ee444e10b774b24f561bb50bf656c51b20075a06..e7f082f610e3bfbd71933e6757faf9c38a9d84e2 100644
--- a/chrome/browser/ssl/ssl_browser_tests.cc
+++ b/chrome/browser/ssl/ssl_browser_tests.cc
@@ -106,6 +106,7 @@
#include "net/ssl/ssl_info.h"
#include "net/test/cert_test_util.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "net/test/embedded_test_server/http_request.h"
#include "net/test/embedded_test_server/request_handler_util.h"
#include "net/test/spawned_test_server/spawned_test_server.h"
#include "net/test/test_certificate_data.h"
@@ -3603,10 +3604,56 @@ IN_PROC_BROWSER_TEST_F(SSLNetworkTimeBrowserTest,
TriggerTimeResponse();
}
+namespace {
+
+// Fails with a CHECK for all requests over HTTP except for favicons. This is to
+// ensure that name mismatch redirect feature's suggest URL ping stops on
+// redirects and never hits an HTTP URL.
+class HttpNameMismatchPingInterceptor : public net::URLRequestInterceptor {
+ public:
+ HttpNameMismatchPingInterceptor() {}
+ ~HttpNameMismatchPingInterceptor() override {}
+
+ net::URLRequestJob* MaybeInterceptRequest(
+ net::URLRequest* request,
+ net::NetworkDelegate* delegate) const override {
+ if (request->url().path() == "/favicon.ico") {
+ // When a page doesn't list a favicon, a favicon request is automatically
+ // made over HTTP. These are harmless and don't leak the original page's
+ // URL, so ignore them.
+ return nullptr;
+ }
+
+ EXPECT_TRUE(false)
+ << "Name mismatch pings must never be over HTTP. This request was for "
+ << request->url();
+ return nullptr;
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(HttpNameMismatchPingInterceptor);
+};
+
+void SetUpHttpNameMismatchPingInterceptorOnIOThread() {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ // Add interceptors for HTTP versions of example.org and www.example.org.
+ // These are the hostnames used in the tests, and we never want them to be
+ // contacted over HTTP.
+ net::URLRequestFilter::GetInstance()->AddHostnameInterceptor(
+ "http", "example.org",
+ std::unique_ptr<HttpNameMismatchPingInterceptor>(
+ new HttpNameMismatchPingInterceptor()));
+ net::URLRequestFilter::GetInstance()->AddHostnameInterceptor(
+ "http", "www.example.org",
+ std::unique_ptr<HttpNameMismatchPingInterceptor>(
+ new HttpNameMismatchPingInterceptor()));
+}
+
+} // namespace
+
class CommonNameMismatchBrowserTest : public CertVerifierBrowserTest {
public:
CommonNameMismatchBrowserTest() : CertVerifierBrowserTest() {}
- ~CommonNameMismatchBrowserTest() override {}
void SetUpCommandLine(base::CommandLine* command_line) override {
// Enable finch experiment for SSL common name mismatch handling.
@@ -3617,6 +3664,15 @@ class CommonNameMismatchBrowserTest : public CertVerifierBrowserTest {
void SetUpOnMainThread() override {
CertVerifierBrowserTest::SetUpOnMainThread();
host_resolver()->AddRule("*", "127.0.0.1");
+ content::BrowserThread::PostTask(
+ content::BrowserThread::IO, FROM_HERE,
+ base::Bind(&SetUpHttpNameMismatchPingInterceptorOnIOThread));
+ }
+
+ void TearDownOnMainThread() override {
+ content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
+ base::Bind(&CleanUpOnIOThread));
+ CertVerifierBrowserTest::TearDownOnMainThread();
}
};
@@ -3625,14 +3681,14 @@ class CommonNameMismatchBrowserTest : public CertVerifierBrowserTest {
// mail.example.com.
IN_PROC_BROWSER_TEST_F(CommonNameMismatchBrowserTest,
ShouldShowWWWSubdomainMismatchInterstitial) {
- net::EmbeddedTestServer https_server_example_domain_(
+ net::EmbeddedTestServer https_server_example_domain(
net::EmbeddedTestServer::TYPE_HTTPS);
- https_server_example_domain_.ServeFilesFromSourceDirectory(
+ https_server_example_domain.ServeFilesFromSourceDirectory(
base::FilePath(kDocRoot));
- ASSERT_TRUE(https_server_example_domain_.Start());
+ ASSERT_TRUE(https_server_example_domain.Start());
scoped_refptr<net::X509Certificate> cert =
- https_server_example_domain_.GetCertificate();
+ https_server_example_domain.GetCertificate();
// Use the "spdy_pooling.pem" cert which has "mail.example.com"
// as one of its SANs.
@@ -3656,11 +3712,11 @@ IN_PROC_BROWSER_TEST_F(CommonNameMismatchBrowserTest,
// Use a complex URL to ensure the path, etc., are preserved. The path itself
// does not matter.
- GURL https_server_url =
- https_server_example_domain_.GetURL("/ssl/google.html?a=b#anchor");
+ const GURL https_server_url =
+ https_server_example_domain.GetURL("/ssl/google.html?a=b#anchor");
GURL::Replacements replacements;
replacements.SetHostStr("www.mail.example.com");
- GURL https_server_mismatched_url =
+ const GURL https_server_mismatched_url =
https_server_url.ReplaceComponents(replacements);
WebContents* contents = browser()->tab_strip_model()->GetActiveWebContents();
@@ -3685,14 +3741,14 @@ IN_PROC_BROWSER_TEST_F(CommonNameMismatchBrowserTest,
// for www.example.org. Verify that the page redirects to www.example.org.
IN_PROC_BROWSER_TEST_F(CommonNameMismatchBrowserTest,
CheckWWWSubdomainMismatchInverse) {
- net::EmbeddedTestServer https_server_example_domain_(
+ net::EmbeddedTestServer https_server_example_domain(
net::EmbeddedTestServer::TYPE_HTTPS);
- https_server_example_domain_.ServeFilesFromSourceDirectory(
+ https_server_example_domain.ServeFilesFromSourceDirectory(
base::FilePath(kDocRoot));
- ASSERT_TRUE(https_server_example_domain_.Start());
+ ASSERT_TRUE(https_server_example_domain.Start());
scoped_refptr<net::X509Certificate> cert =
- https_server_example_domain_.GetCertificate();
+ https_server_example_domain.GetCertificate();
net::CertVerifyResult verify_result;
verify_result.verified_cert =
@@ -3709,11 +3765,11 @@ IN_PROC_BROWSER_TEST_F(CommonNameMismatchBrowserTest,
mock_cert_verifier()->AddResultForCertAndHost(cert.get(), "www.example.org",
verify_result_valid, net::OK);
- GURL https_server_url =
- https_server_example_domain_.GetURL("/ssl/google.html?a=b");
+ const GURL https_server_url =
+ https_server_example_domain.GetURL("/ssl/google.html?a=b");
GURL::Replacements replacements;
replacements.SetHostStr("example.org");
- GURL https_server_mismatched_url =
+ const GURL https_server_mismatched_url =
https_server_url.ReplaceComponents(replacements);
WebContents* contents = browser()->tab_strip_model()->GetActiveWebContents();
@@ -3729,6 +3785,85 @@ IN_PROC_BROWSER_TEST_F(CommonNameMismatchBrowserTest,
AuthState::NONE);
}
+namespace {
+// Redirects incoming request to http://example.org.
+std::unique_ptr<net::test_server::HttpResponse> HTTPSToHTTPRedirectHandler(
+ const net::EmbeddedTestServer* test_server,
+ const net::test_server::HttpRequest& request) {
+ GURL::Replacements replacements;
+ replacements.SetHostStr("example.org");
+ replacements.SetSchemeStr("http");
+ const GURL redirect_url =
+ test_server->base_url().ReplaceComponents(replacements);
+
+ std::unique_ptr<net::test_server::BasicHttpResponse> http_response(
+ new net::test_server::BasicHttpResponse);
+ http_response->set_code(net::HTTP_MOVED_PERMANENTLY);
+ http_response->AddCustomHeader("Location", redirect_url.spec());
+ return std::move(http_response);
+}
+} // namespace
+
+// Common name mismatch handling feature should ignore redirects when pinging
+// the suggested hostname. Visit the URL example.org on a server that presents a
+// valid certificate for www.example.org. In this case, www.example.org
+// redirects to http://example.org, and the SSL error should not be redirected
+// to this URL.
+IN_PROC_BROWSER_TEST_F(CommonNameMismatchBrowserTest,
+ WWWSubdomainMismatch_StopOnRedirects) {
+ net::EmbeddedTestServer https_server_example_domain(
+ net::EmbeddedTestServer::TYPE_HTTPS);
+
+ // Redirect all URLs to http://example.org. Since this test will trigger only
+ // one request to check the suggested URL, redirecting all requests is OK.
+ // We would normally use content::SetupCrossSiteRedirector here, but that
+ // function does not support https to http redirects.
+ // This must be done before ServeFilesFromSourceDirectory(), otherwise the
+ // test server will serve files instead of redirecting requests to them.
+ https_server_example_domain.RegisterRequestHandler(
+ base::Bind(&HTTPSToHTTPRedirectHandler, &https_server_example_domain));
+
+ https_server_example_domain.ServeFilesFromSourceDirectory(
+ base::FilePath(kDocRoot));
+
+ ASSERT_TRUE(https_server_example_domain.Start());
+
+ scoped_refptr<net::X509Certificate> cert =
+ https_server_example_domain.GetCertificate();
+
+ net::CertVerifyResult verify_result;
+ verify_result.verified_cert =
+ net::ImportCertFromFile(net::GetTestCertsDirectory(), "spdy_pooling.pem");
+ verify_result.cert_status = net::CERT_STATUS_COMMON_NAME_INVALID;
+
+ mock_cert_verifier()->AddResultForCertAndHost(
+ cert.get(), "example.org", verify_result,
+ net::ERR_CERT_COMMON_NAME_INVALID);
+
+ net::CertVerifyResult verify_result_valid;
+ verify_result_valid.verified_cert =
+ net::ImportCertFromFile(net::GetTestCertsDirectory(), "spdy_pooling.pem");
+ mock_cert_verifier()->AddResultForCertAndHost(cert.get(), "www.example.org",
+ verify_result_valid, net::OK);
+
+ // The user will visit https://example.org:port/ssl/blank.html.
+ GURL::Replacements replacements;
+ replacements.SetHostStr("example.org");
+ const GURL https_server_mismatched_url =
+ https_server_example_domain.GetURL("/ssl/blank.html")
+ .ReplaceComponents(replacements);
+
+ // Should simply show an interstitial, because the suggested URL
+ // (https://www.example.org) redirected to http://example.org.
+ WebContents* contents = browser()->tab_strip_model()->GetActiveWebContents();
+ ui_test_utils::NavigateToURL(browser(), https_server_mismatched_url);
+ WaitForInterstitialAttach(contents);
+
+ CheckSecurityState(contents, net::CERT_STATUS_COMMON_NAME_INVALID,
+ security_state::DANGEROUS,
+ AuthState::SHOWING_INTERSTITIAL);
+}
+
// Tests this scenario:
// - |CommonNameMismatchHandler| does not give a callback as it's set into the
// state |IGNORE_REQUESTS_FOR_TESTING|. So no suggested URL check result can
@@ -3739,14 +3874,14 @@ IN_PROC_BROWSER_TEST_F(CommonNameMismatchBrowserTest,
// - Stopping the page load shouldn't result in any interstitials.
IN_PROC_BROWSER_TEST_F(CommonNameMismatchBrowserTest,
InterstitialStopNavigationWhileLoading) {
- net::EmbeddedTestServer https_server_example_domain_(
+ net::EmbeddedTestServer https_server_example_domain(
net::EmbeddedTestServer::TYPE_HTTPS);
- https_server_example_domain_.ServeFilesFromSourceDirectory(
+ https_server_example_domain.ServeFilesFromSourceDirectory(
base::FilePath(kDocRoot));
- ASSERT_TRUE(https_server_example_domain_.Start());
+ ASSERT_TRUE(https_server_example_domain.Start());
scoped_refptr<net::X509Certificate> cert =
- https_server_example_domain_.GetCertificate();
+ https_server_example_domain.GetCertificate();
net::CertVerifyResult verify_result;
verify_result.verified_cert =
@@ -3763,11 +3898,11 @@ IN_PROC_BROWSER_TEST_F(CommonNameMismatchBrowserTest,
mock_cert_verifier()->AddResultForCertAndHost(cert.get(), "mail.example.com",
verify_result_valid, net::OK);
- GURL https_server_url =
- https_server_example_domain_.GetURL("/ssl/google.html?a=b");
+ const GURL https_server_url =
+ https_server_example_domain.GetURL("/ssl/google.html?a=b");
GURL::Replacements replacements;
replacements.SetHostStr("www.mail.example.com");
- GURL https_server_mismatched_url =
+ const GURL https_server_mismatched_url =
https_server_url.ReplaceComponents(replacements);
WebContents* contents = browser()->tab_strip_model()->GetActiveWebContents();
@@ -3802,14 +3937,14 @@ IN_PROC_BROWSER_TEST_F(CommonNameMismatchBrowserTest,
// result is the same. (i.e. page load stops, no interstitials shown)
IN_PROC_BROWSER_TEST_F(CommonNameMismatchBrowserTest,
InterstitialReloadNavigationWhileLoading) {
- net::EmbeddedTestServer https_server_example_domain_(
+ net::EmbeddedTestServer https_server_example_domain(
net::EmbeddedTestServer::TYPE_HTTPS);
- https_server_example_domain_.ServeFilesFromSourceDirectory(
+ https_server_example_domain.ServeFilesFromSourceDirectory(
base::FilePath(kDocRoot));
- ASSERT_TRUE(https_server_example_domain_.Start());
+ ASSERT_TRUE(https_server_example_domain.Start());
scoped_refptr<net::X509Certificate> cert =
- https_server_example_domain_.GetCertificate();
+ https_server_example_domain.GetCertificate();
net::CertVerifyResult verify_result;
verify_result.verified_cert =
@@ -3826,11 +3961,11 @@ IN_PROC_BROWSER_TEST_F(CommonNameMismatchBrowserTest,
mock_cert_verifier()->AddResultForCertAndHost(cert.get(), "mail.example.com",
verify_result_valid, net::OK);
- GURL https_server_url =
- https_server_example_domain_.GetURL("/ssl/google.html?a=b");
+ const GURL https_server_url =
+ https_server_example_domain.GetURL("/ssl/google.html?a=b");
GURL::Replacements replacements;
replacements.SetHostStr("www.mail.example.com");
- GURL https_server_mismatched_url =
+ const GURL https_server_mismatched_url =
https_server_url.ReplaceComponents(replacements);
WebContents* contents = browser()->tab_strip_model()->GetActiveWebContents();
@@ -3863,14 +3998,14 @@ IN_PROC_BROWSER_TEST_F(CommonNameMismatchBrowserTest,
// new page should load, and no interstitials should be shown.
IN_PROC_BROWSER_TEST_F(CommonNameMismatchBrowserTest,
InterstitialNavigateAwayWhileLoading) {
- net::EmbeddedTestServer https_server_example_domain_(
+ net::EmbeddedTestServer https_server_example_domain(
net::EmbeddedTestServer::TYPE_HTTPS);
- https_server_example_domain_.ServeFilesFromSourceDirectory(
+ https_server_example_domain.ServeFilesFromSourceDirectory(
base::FilePath(kDocRoot));
- ASSERT_TRUE(https_server_example_domain_.Start());
+ ASSERT_TRUE(https_server_example_domain.Start());
scoped_refptr<net::X509Certificate> cert =
- https_server_example_domain_.GetCertificate();
+ https_server_example_domain.GetCertificate();
net::CertVerifyResult verify_result;
verify_result.verified_cert =
@@ -3887,11 +4022,11 @@ IN_PROC_BROWSER_TEST_F(CommonNameMismatchBrowserTest,
mock_cert_verifier()->AddResultForCertAndHost(cert.get(), "mail.example.com",
verify_result_valid, net::OK);
- GURL https_server_url =
- https_server_example_domain_.GetURL("/ssl/google.html?a=b");
+ const GURL https_server_url =
+ https_server_example_domain.GetURL("/ssl/google.html?a=b");
GURL::Replacements replacements;
replacements.SetHostStr("www.mail.example.com");
- GURL https_server_mismatched_url =
+ const GURL https_server_mismatched_url =
https_server_url.ReplaceComponents(replacements);
WebContents* contents = browser()->tab_strip_model()->GetActiveWebContents();
« no previous file with comments | « chrome/browser/ssl/common_name_mismatch_handler.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698