diff options
author | palmer@chromium.org <palmer@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-30 21:20:46 +0000 |
---|---|---|
committer | palmer@chromium.org <palmer@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-30 21:20:46 +0000 |
commit | 242d8565075bb8c8f0fb3ef6a7651b39e6b67241 (patch) | |
tree | 827ac26a7b1988ba56d38b628cf020a03e6c1736 /net | |
parent | f9ba71d83695d37f061b6657485b390ea5d76261 (diff) | |
download | chromium_src-242d8565075bb8c8f0fb3ef6a7651b39e6b67241.zip chromium_src-242d8565075bb8c8f0fb3ef6a7651b39e6b67241.tar.gz chromium_src-242d8565075bb8c8f0fb3ef6a7651b39e6b67241.tar.bz2 |
Process only the first Strict-Transport-Security header.
In accordance with the specification.
BUG=156147
Review URL: https://chromiumcodereview.appspot.com/11192045
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@165013 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r-- | net/data/url_request_unittest/hsts-headers.html | 1 | ||||
-rw-r--r-- | net/data/url_request_unittest/hsts-headers.html.mock-http-headers | 6 | ||||
-rw-r--r-- | net/data/url_request_unittest/hsts-multiple-headers.html | 1 | ||||
-rw-r--r-- | net/data/url_request_unittest/hsts-multiple-headers.html.mock-http-headers | 7 | ||||
-rw-r--r-- | net/http/http_util.cc | 5 | ||||
-rw-r--r-- | net/url_request/url_request_http_job.cc | 9 | ||||
-rw-r--r-- | net/url_request/url_request_test_util.cc | 4 | ||||
-rw-r--r-- | net/url_request/url_request_unittest.cc | 55 |
8 files changed, 87 insertions, 1 deletions
diff --git a/net/data/url_request_unittest/hsts-headers.html b/net/data/url_request_unittest/hsts-headers.html new file mode 100644 index 0000000..364322d --- /dev/null +++ b/net/data/url_request_unittest/hsts-headers.html @@ -0,0 +1 @@ +This file is boring; all the action's in the .mock-http-headers. diff --git a/net/data/url_request_unittest/hsts-headers.html.mock-http-headers b/net/data/url_request_unittest/hsts-headers.html.mock-http-headers new file mode 100644 index 0000000..e397296 --- /dev/null +++ b/net/data/url_request_unittest/hsts-headers.html.mock-http-headers @@ -0,0 +1,6 @@ +HTTP/1.1 200 OK +Cache-Control: private +Content-Type: text/html; charset=ISO-8859-1 +X-Multiple-Entries: a +X-Multiple-Entries: b +Strict-Transport-Security: max-age=123; includeSubdomains diff --git a/net/data/url_request_unittest/hsts-multiple-headers.html b/net/data/url_request_unittest/hsts-multiple-headers.html new file mode 100644 index 0000000..364322d --- /dev/null +++ b/net/data/url_request_unittest/hsts-multiple-headers.html @@ -0,0 +1 @@ +This file is boring; all the action's in the .mock-http-headers. diff --git a/net/data/url_request_unittest/hsts-multiple-headers.html.mock-http-headers b/net/data/url_request_unittest/hsts-multiple-headers.html.mock-http-headers new file mode 100644 index 0000000..e83b722 --- /dev/null +++ b/net/data/url_request_unittest/hsts-multiple-headers.html.mock-http-headers @@ -0,0 +1,7 @@ +HTTP/1.1 200 OK +Cache-Control: private +Content-Type: text/html; charset=ISO-8859-1 +X-Multiple-Entries: a +X-Multiple-Entries: b +Strict-Transport-Security: max-age=123 +Strict-Transport-Security: max-age=123; includeSubdomains diff --git a/net/http/http_util.cc b/net/http/http_util.cc index 43be4f0..44d7330 100644 --- a/net/http/http_util.cc +++ b/net/http/http_util.cc @@ -392,7 +392,10 @@ bool HttpUtil::IsNonCoalescingHeader(string::const_iterator name_begin, // The format of auth-challenges mixes both space separated tokens and // comma separated properties, so coalescing on comma won't work. "www-authenticate", - "proxy-authenticate" + "proxy-authenticate", + // STS specifies that UAs must not process any STS headers after the first + // one. + "strict-transport-security" }; for (size_t i = 0; i < arraysize(kNonCoalescingHeaders); ++i) { if (LowerCaseEqualsASCII(name_begin, name_end, kNonCoalescingHeaders[i])) diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc index aab892f..2860e7e 100644 --- a/net/url_request/url_request_http_job.cc +++ b/net/url_request/url_request_http_job.cc @@ -701,7 +701,16 @@ void URLRequestHttpJob::ProcessStrictTransportSecurityHeader() { void* iter = NULL; base::Time now = base::Time::Now(); + // http://tools.ietf.org/html/draft-ietf-websec-strict-transport-sec: + // + // If a UA receives more than one STS header field in a HTTP response + // message over secure transport, then the UA MUST process only the + // first such header field. + bool seen_sts = false; while (headers->EnumerateHeader(&iter, "Strict-Transport-Security", &value)) { + if (seen_sts) + return; + seen_sts = true; TransportSecurityState::DomainState domain_state; if (domain_state.ParseSTSHeader(now, value)) security_state->EnableHost(host, domain_state); diff --git a/net/url_request/url_request_test_util.cc b/net/url_request/url_request_test_util.cc index 33ea742..28da79f 100644 --- a/net/url_request/url_request_test_util.cc +++ b/net/url_request/url_request_test_util.cc @@ -85,6 +85,10 @@ void TestURLRequestContext::Init() { context_storage_.set_http_server_properties( new net::HttpServerPropertiesImpl); } + if (!transport_security_state()) { + context_storage_.set_transport_security_state( + new net::TransportSecurityState()); + } net::HttpNetworkSession::Params params; params.host_resolver = host_resolver(); params.cert_verifier = cert_verifier(); diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc index 402b773..38b574a 100644 --- a/net/url_request/url_request_unittest.cc +++ b/net/url_request/url_request_unittest.cc @@ -3060,6 +3060,61 @@ TEST_F(URLRequestTestHTTP, ResponseHeadersTest) { EXPECT_EQ("a, b", header); } +TEST_F(URLRequestTestHTTP, ProcessSTS) { + TestServer::SSLOptions ssl_options; + TestServer https_test_server( + TestServer::TYPE_HTTPS, + ssl_options, + FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))); + ASSERT_TRUE(https_test_server.Start()); + + TestDelegate d; + URLRequest request( + https_test_server.GetURL("files/hsts-headers.html"), + &d, + &default_context_); + request.Start(); + MessageLoop::current()->Run(); + + TransportSecurityState* security_state = + default_context_.transport_security_state(); + bool sni_available = true; + TransportSecurityState::DomainState domain_state; + EXPECT_TRUE(security_state->GetDomainState( + TestServer::kLocalhost, sni_available, &domain_state)); + EXPECT_EQ(TransportSecurityState::DomainState::MODE_FORCE_HTTPS, + domain_state.upgrade_mode); + EXPECT_TRUE(domain_state.include_subdomains); +} + +TEST_F(URLRequestTestHTTP, ProcessSTSOnce) { + TestServer::SSLOptions ssl_options; + TestServer https_test_server( + TestServer::TYPE_HTTPS, + ssl_options, + FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))); + ASSERT_TRUE(https_test_server.Start()); + + TestDelegate d; + URLRequest request( + https_test_server.GetURL("files/hsts-multiple-headers.html"), + &d, + &default_context_); + request.Start(); + MessageLoop::current()->Run(); + + // We should have set parameters from the first header, not the second. + TransportSecurityState* security_state = + default_context_.transport_security_state(); + bool sni_available = true; + TransportSecurityState::DomainState domain_state; + EXPECT_TRUE(security_state->GetDomainState( + TestServer::kLocalhost, sni_available, &domain_state)); + EXPECT_EQ(TransportSecurityState::DomainState::MODE_FORCE_HTTPS, + domain_state.upgrade_mode); + EXPECT_FALSE(domain_state.include_subdomains); +} + TEST_F(URLRequestTestHTTP, ContentTypeNormalizationTest) { ASSERT_TRUE(test_server_.Start()); |