summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorbengr@google.com <bengr@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-05 07:15:00 +0000
committerbengr@google.com <bengr@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-05 07:15:00 +0000
commit8c84319180b6134e337fa105c081943fdf3a485e (patch)
treefb01d6a11f148d54b1b0bba3221acdb9e160e877 /net
parent5a4a7abc5253321b092cc7455100197a9914a34b (diff)
downloadchromium_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.cc82
-rw-r--r--net/http/http_network_transaction_spdy2_unittest.cc82
-rw-r--r--net/http/http_network_transaction_spdy3_unittest.cc82
-rw-r--r--net/spdy/spdy_session.cc10
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());