diff options
author | bengr@google.com <bengr@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-05 07:15:00 +0000 |
---|---|---|
committer | bengr@google.com <bengr@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-05 07:15:00 +0000 |
commit | 8c84319180b6134e337fa105c081943fdf3a485e (patch) | |
tree | fb01d6a11f148d54b1b0bba3221acdb9e160e877 /net | |
parent | 5a4a7abc5253321b092cc7455100197a9914a34b (diff) | |
download | chromium_src-8c84319180b6134e337fa105c081943fdf3a485e.zip chromium_src-8c84319180b6134e337fa105c081943fdf3a485e.tar.gz chromium_src-8c84319180b6134e337fa105c081943fdf3a485e.tar.bz2 |
disallow proxy push of HTTPS content
A SPDY proxy that is trusted explicitly should still not be able
to push HTTPS content.
BUG=113427
TEST=
Review URL: http://codereview.chromium.org/9968055
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@130851 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r-- | net/http/http_network_transaction_spdy21_unittest.cc | 82 | ||||
-rw-r--r-- | net/http/http_network_transaction_spdy2_unittest.cc | 82 | ||||
-rw-r--r-- | net/http/http_network_transaction_spdy3_unittest.cc | 82 | ||||
-rw-r--r-- | net/spdy/spdy_session.cc | 10 |
4 files changed, 255 insertions, 1 deletions
diff --git a/net/http/http_network_transaction_spdy21_unittest.cc b/net/http/http_network_transaction_spdy21_unittest.cc index 93b50a3..c77e64e 100644 --- a/net/http/http_network_transaction_spdy21_unittest.cc +++ b/net/http/http_network_transaction_spdy21_unittest.cc @@ -4990,6 +4990,88 @@ TEST_F(HttpNetworkTransactionSpdy21Test, CrossOriginProxyPush) { session->CloseAllConnections(); } +// Test that an explicitly trusted SPDY proxy cannot push HTTPS content. +TEST_F(HttpNetworkTransactionSpdy21Test, CrossOriginProxyPushCorrectness) { + HttpRequestInfo request; + + request.method = "GET"; + request.url = GURL("http://www.google.com/"); + + // Enable cross-origin push. + net::SpdySession::set_allow_spdy_proxy_push_across_origins("myproxy:70"); + + // Configure against https proxy server "myproxy:70". + SessionDependencies session_deps( + ProxyService::CreateFixed("https://myproxy:70")); + CapturingBoundNetLog log(CapturingNetLog::kUnbounded); + session_deps.net_log = log.bound().net_log(); + scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); + + scoped_ptr<SpdyFrame> + stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false)); + + scoped_ptr<SpdyFrame> push_rst( + ConstructSpdyRstStream(2, REFUSED_STREAM)); + + MockWrite spdy_writes[] = { + CreateMockWrite(*stream1_syn, 1, ASYNC), + CreateMockWrite(*push_rst, 4), + }; + + scoped_ptr<SpdyFrame> + stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1)); + + scoped_ptr<SpdyFrame> + stream1_body(ConstructSpdyBodyFrame(1, true)); + + scoped_ptr<SpdyFrame> + stream2_syn(ConstructSpdyPush(NULL, + 0, + 2, + 1, + "https://www.another-origin.com/foo.dat")); + + MockRead spdy_reads[] = { + CreateMockRead(*stream1_reply, 2, ASYNC), + CreateMockRead(*stream2_syn, 3, ASYNC), + CreateMockRead(*stream1_body, 5, ASYNC), + MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause + }; + + scoped_ptr<OrderedSocketData> spdy_data( + new OrderedSocketData( + spdy_reads, arraysize(spdy_reads), + spdy_writes, arraysize(spdy_writes))); + session_deps.socket_factory.AddSocketDataProvider(spdy_data.get()); + // Negotiate SPDY to the proxy + SSLSocketDataProvider proxy(ASYNC, OK); + proxy.SetNextProto(kProtoSPDY21); + session_deps.socket_factory.AddSSLSocketDataProvider(&proxy); + + scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); + TestCompletionCallback callback; + int rv = trans->Start(&request, callback.callback(), log.bound()); + EXPECT_EQ(ERR_IO_PENDING, rv); + + rv = callback.WaitForResult(); + EXPECT_EQ(OK, rv); + const HttpResponseInfo* response = trans->GetResponseInfo(); + + ASSERT_TRUE(response != NULL); + EXPECT_TRUE(response->headers->IsKeepAlive()); + + EXPECT_EQ(200, response->headers->response_code()); + EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); + + std::string response_data; + rv = ReadTransaction(trans.get(), &response_data); + EXPECT_EQ(OK, rv); + EXPECT_EQ("hello!", response_data); + + trans.reset(); + session->CloseAllConnections(); +} + // Test HTTPS connections to a site with a bad certificate, going through an // HTTPS proxy TEST_F(HttpNetworkTransactionSpdy21Test, HTTPSBadCertificateViaHttpsProxy) { diff --git a/net/http/http_network_transaction_spdy2_unittest.cc b/net/http/http_network_transaction_spdy2_unittest.cc index 0ed4629..f52217b 100644 --- a/net/http/http_network_transaction_spdy2_unittest.cc +++ b/net/http/http_network_transaction_spdy2_unittest.cc @@ -4990,6 +4990,88 @@ TEST_F(HttpNetworkTransactionSpdy2Test, CrossOriginProxyPush) { session->CloseAllConnections(); } +// Test that an explicitly trusted SPDY proxy cannot push HTTPS content. +TEST_F(HttpNetworkTransactionSpdy2Test, CrossOriginProxyPushCorrectness) { + HttpRequestInfo request; + + request.method = "GET"; + request.url = GURL("http://www.google.com/"); + + // Enable cross-origin push. + net::SpdySession::set_allow_spdy_proxy_push_across_origins("myproxy:70"); + + // Configure against https proxy server "myproxy:70". + SessionDependencies session_deps( + ProxyService::CreateFixed("https://myproxy:70")); + CapturingBoundNetLog log(CapturingNetLog::kUnbounded); + session_deps.net_log = log.bound().net_log(); + scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); + + scoped_ptr<SpdyFrame> + stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false)); + + scoped_ptr<SpdyFrame> push_rst( + ConstructSpdyRstStream(2, REFUSED_STREAM)); + + MockWrite spdy_writes[] = { + CreateMockWrite(*stream1_syn, 1, ASYNC), + CreateMockWrite(*push_rst, 4), + }; + + scoped_ptr<SpdyFrame> + stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1)); + + scoped_ptr<SpdyFrame> + stream1_body(ConstructSpdyBodyFrame(1, true)); + + scoped_ptr<SpdyFrame> + stream2_syn(ConstructSpdyPush(NULL, + 0, + 2, + 1, + "https://www.another-origin.com/foo.dat")); + + MockRead spdy_reads[] = { + CreateMockRead(*stream1_reply, 2, ASYNC), + CreateMockRead(*stream2_syn, 3, ASYNC), + CreateMockRead(*stream1_body, 5, ASYNC), + MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause + }; + + scoped_ptr<OrderedSocketData> spdy_data( + new OrderedSocketData( + spdy_reads, arraysize(spdy_reads), + spdy_writes, arraysize(spdy_writes))); + session_deps.socket_factory.AddSocketDataProvider(spdy_data.get()); + // Negotiate SPDY to the proxy + SSLSocketDataProvider proxy(ASYNC, OK); + proxy.SetNextProto(kProtoSPDY2); + session_deps.socket_factory.AddSSLSocketDataProvider(&proxy); + + scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); + TestCompletionCallback callback; + int rv = trans->Start(&request, callback.callback(), log.bound()); + EXPECT_EQ(ERR_IO_PENDING, rv); + + rv = callback.WaitForResult(); + EXPECT_EQ(OK, rv); + const HttpResponseInfo* response = trans->GetResponseInfo(); + + ASSERT_TRUE(response != NULL); + EXPECT_TRUE(response->headers->IsKeepAlive()); + + EXPECT_EQ(200, response->headers->response_code()); + EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); + + std::string response_data; + rv = ReadTransaction(trans.get(), &response_data); + EXPECT_EQ(OK, rv); + EXPECT_EQ("hello!", response_data); + + trans.reset(); + session->CloseAllConnections(); +} + // Test HTTPS connections to a site with a bad certificate, going through an // HTTPS proxy TEST_F(HttpNetworkTransactionSpdy2Test, HTTPSBadCertificateViaHttpsProxy) { diff --git a/net/http/http_network_transaction_spdy3_unittest.cc b/net/http/http_network_transaction_spdy3_unittest.cc index c121ef0..efbcf39 100644 --- a/net/http/http_network_transaction_spdy3_unittest.cc +++ b/net/http/http_network_transaction_spdy3_unittest.cc @@ -4991,6 +4991,88 @@ TEST_F(HttpNetworkTransactionSpdy3Test, CrossOriginProxyPush) { session->CloseAllConnections(); } +// Test that an explicitly trusted SPDY proxy cannot push HTTPS content. +TEST_F(HttpNetworkTransactionSpdy3Test, CrossOriginProxyPushCorrectness) { + HttpRequestInfo request; + + request.method = "GET"; + request.url = GURL("http://www.google.com/"); + + // Enable cross-origin push. + net::SpdySession::set_allow_spdy_proxy_push_across_origins("myproxy:70"); + + // Configure against https proxy server "myproxy:70". + SessionDependencies session_deps( + ProxyService::CreateFixed("https://myproxy:70")); + CapturingBoundNetLog log(CapturingNetLog::kUnbounded); + session_deps.net_log = log.bound().net_log(); + scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); + + scoped_ptr<SpdyFrame> + stream1_syn(ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false)); + + scoped_ptr<SpdyFrame> push_rst( + ConstructSpdyRstStream(2, REFUSED_STREAM)); + + MockWrite spdy_writes[] = { + CreateMockWrite(*stream1_syn, 1, ASYNC), + CreateMockWrite(*push_rst, 4), + }; + + scoped_ptr<SpdyFrame> + stream1_reply(ConstructSpdyGetSynReply(NULL, 0, 1)); + + scoped_ptr<SpdyFrame> + stream1_body(ConstructSpdyBodyFrame(1, true)); + + scoped_ptr<SpdyFrame> + stream2_syn(ConstructSpdyPush(NULL, + 0, + 2, + 1, + "https://www.another-origin.com/foo.dat")); + + MockRead spdy_reads[] = { + CreateMockRead(*stream1_reply, 2, ASYNC), + CreateMockRead(*stream2_syn, 3, ASYNC), + CreateMockRead(*stream1_body, 5, ASYNC), + MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause + }; + + scoped_ptr<OrderedSocketData> spdy_data( + new OrderedSocketData( + spdy_reads, arraysize(spdy_reads), + spdy_writes, arraysize(spdy_writes))); + session_deps.socket_factory.AddSocketDataProvider(spdy_data.get()); + // Negotiate SPDY to the proxy + SSLSocketDataProvider proxy(ASYNC, OK); + proxy.SetNextProto(kProtoSPDY3); + session_deps.socket_factory.AddSSLSocketDataProvider(&proxy); + + scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); + TestCompletionCallback callback; + int rv = trans->Start(&request, callback.callback(), log.bound()); + EXPECT_EQ(ERR_IO_PENDING, rv); + + rv = callback.WaitForResult(); + EXPECT_EQ(OK, rv); + const HttpResponseInfo* response = trans->GetResponseInfo(); + + ASSERT_TRUE(response != NULL); + EXPECT_TRUE(response->headers->IsKeepAlive()); + + EXPECT_EQ(200, response->headers->response_code()); + EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); + + std::string response_data; + rv = ReadTransaction(trans.get(), &response_data); + EXPECT_EQ(OK, rv); + EXPECT_EQ("hello!", response_data); + + trans.reset(); + session->CloseAllConnections(); +} + // Test HTTPS connections to a site with a bad certificate, going through an // HTTPS proxy TEST_F(HttpNetworkTransactionSpdy3Test, HTTPSBadCertificateViaHttpsProxy) { diff --git a/net/spdy/spdy_session.cc b/net/spdy/spdy_session.cc index 7f3fa70..cb2aad8 100644 --- a/net/spdy/spdy_session.cc +++ b/net/spdy/spdy_session.cc @@ -1448,7 +1448,15 @@ void SpdySession::OnSynStream( // Check that the SYN advertises the same origin as its associated stream. // Bypass this check if and only if this session is with a SPDY proxy that // is trusted explicitly via the allow_spdy_proxy_push_across_origins switch. - if (!allow_spdy_proxy_push_across_origins_.Equals(host_port_pair())) { + if (allow_spdy_proxy_push_across_origins_.Equals(host_port_pair())) { + // Disallow pushing of HTTPS content. + if (gurl.SchemeIs("https")) { + ResetStream(stream_id, REFUSED_STREAM, + base::StringPrintf( + "Rejected push of Cross Origin HTTPS content %d", + associated_stream_id)); + } + } else { scoped_refptr<SpdyStream> associated_stream = active_streams_[associated_stream_id]; GURL associated_url(associated_stream->GetUrl()); |