diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc index aadbb4eb24ce5..3c2eae1ece92c 100644 --- a/net/http/http_network_transaction_unittest.cc +++ b/net/http/http_network_transaction_unittest.cc @@ -9314,7 +9314,7 @@ TEST_F(HttpNetworkTransactionTest, NTLMOverHttp2WithWebsockets) { session_deps_.socket_factory->AddSocketDataProvider(&data1); SSLSocketDataProvider ssl1(ASYNC, OK); // When creating the second connection, only HTTP/1.1 should be allowed. - ssl1.next_protos_expected_in_ssl_config = NextProtoVector{}; + ssl1.next_protos_expected_in_ssl_config = NextProtoVector{kProtoHTTP11}; session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1); session_deps_.enable_websocket_over_http2 = true; diff --git a/net/http/http_stream_factory_job.cc b/net/http/http_stream_factory_job.cc index a831772f819e2..a01b633bec346 100644 --- a/net/http/http_stream_factory_job.cc +++ b/net/http/http_stream_factory_job.cc @@ -831,8 +831,17 @@ int HttpStreamFactory::Job::DoInitConnectionImpl() { if (is_websocket_) { DCHECK(request_info_.socket_tag == SocketTag()); DCHECK_EQ(SecureDnsPolicy::kAllow, request_info_.secure_dns_policy); + // Only offer HTTP/1.1 for WebSockets. Although RFC 8441 defines WebSockets + // over HTTP/2, a single WSS/HTTPS origin may support HTTP over HTTP/2 + // without supporting WebSockets over HTTP/2. Offering HTTP/2 for a fresh + // connection would break such origins. + // + // However, still offer HTTP/1.1 rather than skipping ALPN entirely. While + // this will not change the application protocol (HTTP/1.1 is default), it + // provides hardens against cross-protocol attacks and allows for the False + // Start (RFC 7918) optimization. SSLConfig websocket_server_ssl_config = server_ssl_config_; - websocket_server_ssl_config.alpn_protos.clear(); + websocket_server_ssl_config.alpn_protos = {kProtoHTTP11}; return InitSocketHandleForWebSocketRequest( destination_, request_info_.load_flags, priority_, session_, proxy_info_, websocket_server_ssl_config, proxy_ssl_config_, diff --git a/net/spdy/spdy_network_transaction_unittest.cc b/net/spdy/spdy_network_transaction_unittest.cc index 901ec85aadce4..92a64f2b01655 100644 --- a/net/spdy/spdy_network_transaction_unittest.cc +++ b/net/spdy/spdy_network_transaction_unittest.cc @@ -8719,8 +8719,8 @@ TEST_F(SpdyNetworkTransactionTest, WebSocketOpensNewConnection) { StaticSocketDataProvider data2(reads2, writes2); auto ssl_provider2 = std::make_unique(ASYNC, OK); - // Test that request has empty |alpn_protos|, that is, HTTP/2 is disabled. - ssl_provider2->next_protos_expected_in_ssl_config = NextProtoVector{}; + // Test that the request has HTTP/2 disabled. + ssl_provider2->next_protos_expected_in_ssl_config = {kProtoHTTP11}; // Force socket to use HTTP/1.1, the default protocol without ALPN. ssl_provider2->next_proto = kProtoHTTP11; ssl_provider2->ssl_info.cert = @@ -8842,8 +8842,8 @@ TEST_F(SpdyNetworkTransactionTest, SequencedSocketData data2(MockConnect(ASYNC, ERR_IO_PENDING), reads2, writes2); auto ssl_provider2 = std::make_unique(ASYNC, OK); - // Test that request has empty |alpn_protos|, that is, HTTP/2 is disabled. - ssl_provider2->next_protos_expected_in_ssl_config = NextProtoVector{}; + // Test that the request has HTTP/2 disabled. + ssl_provider2->next_protos_expected_in_ssl_config = {kProtoHTTP11}; // Force socket to use HTTP/1.1, the default protocol without ALPN. ssl_provider2->next_proto = kProtoHTTP11; helper.AddDataWithSSLSocketDataProvider(&data2, std::move(ssl_provider2)); @@ -9118,8 +9118,8 @@ TEST_F(SpdyNetworkTransactionTest, &tunnel_ssl_data2); auto ssl_provider2 = std::make_unique(ASYNC, OK); - // Test that request has empty |alpn_protos|, that is, HTTP/2 is disabled. - ssl_provider2->next_protos_expected_in_ssl_config = NextProtoVector{}; + // Test that the request has HTTP/2 disabled. + ssl_provider2->next_protos_expected_in_ssl_config = {kProtoHTTP11}; // Force socket to use HTTP/1.1, the default protocol without ALPN. ssl_provider2->next_proto = kProtoHTTP11; helper.AddDataWithSSLSocketDataProvider(&data2, std::move(ssl_provider2)); @@ -9384,8 +9384,8 @@ TEST_F(SpdyNetworkTransactionTest, "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")}; StaticSocketDataProvider data2(reads2, writes2); auto ssl_provider2 = std::make_unique(ASYNC, OK); - // Test that request has empty |alpn_protos|, that is, HTTP/2 is disabled. - ssl_provider2->next_protos_expected_in_ssl_config = NextProtoVector{}; + // Test that the request has HTTP/2 disabled. + ssl_provider2->next_protos_expected_in_ssl_config = {kProtoHTTP11}; // Force socket to use HTTP/1.1, the default protocol without ALPN. ssl_provider2->next_proto = kProtoHTTP11; ssl_provider2->ssl_info.cert = @@ -9493,8 +9493,8 @@ TEST_F(SpdyNetworkTransactionTest, WebSocketNegotiatesHttp2) { StaticSocketDataProvider data; auto ssl_provider = std::make_unique(ASYNC, OK); - // Test that request has empty |alpn_protos|, that is, HTTP/2 is disabled. - ssl_provider->next_protos_expected_in_ssl_config = NextProtoVector{}; + // Test that the request has HTTP/2 disabled. + ssl_provider->next_protos_expected_in_ssl_config = {kProtoHTTP11}; // Force socket to use HTTP/2, which should never happen (TLS implementation // should fail TLS handshake if server chooses HTTP/2 without client // advertising support). @@ -9584,8 +9584,8 @@ TEST_F(SpdyNetworkTransactionTest, WebSocketHttp11Required) { "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")}; StaticSocketDataProvider data2(reads2, writes2); auto ssl_provider2 = std::make_unique(ASYNC, OK); - // Test that request has empty |alpn_protos|, that is, HTTP/2 is disabled. - ssl_provider2->next_protos_expected_in_ssl_config = NextProtoVector{}; + // Test that the request has HTTP/2 disabled. + ssl_provider2->next_protos_expected_in_ssl_config = {kProtoHTTP11}; // Force socket to use HTTP/1.1, the default protocol without ALPN. ssl_provider2->next_proto = kProtoHTTP11; ssl_provider2->ssl_info.cert = @@ -9757,7 +9757,7 @@ TEST_F(SpdyNetworkTransactionTest, SecureWebSocketOverHttp2Proxy) { ssl_provider.ssl_info.cert = ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"); // A WebSocket request should not advertise HTTP/2 support. - ssl_provider.next_protos_expected_in_ssl_config = NextProtoVector{}; + ssl_provider.next_protos_expected_in_ssl_config = {kProtoHTTP11}; // This test uses WebSocket over HTTP/1.1. ssl_provider.next_proto = kProtoHTTP11; helper.session_deps()->socket_factory->AddSSLSocketDataProvider( @@ -9817,7 +9817,7 @@ TEST_F(SpdyNetworkTransactionTest, ssl_provider.ssl_info.cert = ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"); // A WebSocket request should not advertise HTTP/2 support. - ssl_provider.next_protos_expected_in_ssl_config = NextProtoVector{}; + ssl_provider.next_protos_expected_in_ssl_config = {kProtoHTTP11}; // The server should not negotiate HTTP/2 over the tunnelled connection, // but it must be handled gracefully if it does. ssl_provider.next_proto = kProtoHTTP2;