Low watch CVSS 4.3 chrome Info Disclosure 🔧 Commit mapped

Overview

Low
Severity
4.3
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactSide-channel information leakage in Network
DescriptionSide-channel information leakage in Network
ComponentNetwork
Sub-componentTCP
Bug ClassInfo Disclosure
Action tierwatch — information disclosure — security-relevant, below the RCE-class bar
Computed by PatchGap's deterministic exploitability ruler from the fixing commit. patch-now = RCE-class & attacker-reachable in a default config, or exploited in the wild; watch = real security signal below that bar; noise = no security relevance.
Tracker497837927
Fix commite904ef795270 (chromium/src) +180/-51
CWECWE-1300
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:N
CISA KEVNot listed
CreditedGoogle
Reported2026-03-30 (per vendor advisory)
Fix landed2026-05-05 (public git)
Disclosed2026-07-29
Patch gap85 days — fix public in source before the advisory

Background

Socket pool size randomization
an xsleaks defense (net::features::kTcpSocketPoolLimitRandomization) that randomly caps a connection pool between its nominal size (e.g. 128) and 2x that, so the observable capacity is non-deterministic.
Cross-site connection-count side channel
a technique where an attacker saturates a shared socket pool and measures when new connections stall to infer another site’s connection activity, which a fixed pool limit makes reliably measurable.
`SetMaxConnectionsPerProxyChain`
the NetworkService method through which the browser propagates per-proxy connection limits (kMaxConnectionsPerProxy / kMaxConnectionsPerProxyForWebSocket) into the network process.
Policy handler
a chrome/browser/policy mapping that binds an enterprise policy key:: to a local-state prefs:: value so admins can control browser behavior.

Root Cause Analysis

Before this change, net::features::kTcpSocketPoolLimitRandomization unconditionally applied randomized capacity to proxy pools, and system_network_context_manager.cc called SetMaxConnectionsPerProxyChain with only the normal and WebSocket clamp values, with no way for an administrator to control whether the randomization applied. Enterprises that pin proxy connection limits via MaxConnectionsPerProxy expected those limits to be authoritative, but the randomization silently allowed up to 2x the configured value, and there was no enterprise gate to opt out of the side-channel defense where it conflicted with deployment constraints.

The fix registers a new boolean pref prefs::kAllowSocketPoolSizeRandomizationForProxies (default true), maps enterprise policy key::kAllowSocketPoolSizeRandomizationForProxies to it, and threads that pref value into a new third argument of SetMaxConnectionsPerProxyChain. This works because the randomized-capacity defense (per xsleaks.dev) is now explicitly policy-gated per the admin’s choice while remaining on by default, so the side-channel hardening is preserved for the common case and controllable where required.

Key insight
The single mistake was that the randomized proxy-pool capacity defense had no enterprise gate, coupling a security mechanism to hard-configured connection limits with no admin override; the fix adds the kAllowSocketPoolSizeRandomizationForProxies policy/pref and threads it into SetMaxConnectionsPerProxyChain so the defense stays default-on but becomes explicitly controllable.

Attack Path

  1. Shared proxy pool A victim routes traffic through a proxy whose per-chain socket pool has a deterministic capacity, and an attacker page shares that same pool.
  2. Saturate connections The attacker opens connections up to the pool limit and observes exactly when further connections stall, since a fixed cap makes the saturation point precisely measurable.
  3. Infer cross-site state By correlating the stall threshold with the victim’s activity, the attacker infers a cross-site connection-count signal that the deterministic limit leaks.
  4. Defense-gating consideration Randomization normally masks the exact threshold; the CL ensures this masking is retained by default (prefs::kAllowSocketPoolSizeRandomizationForProxies = true) rather than left ungoverned, and only disabled by explicit admin policy.

Impact Assessment

An attacker in a web renderer sharing a proxy socket pool with a victim could infer cross-site connection-count information through the deterministic capacity limit, a side-channel information leak in the network stack. The precondition is a shared, non-randomized proxy pool; the change ensures the randomized-capacity defense is on by default and only removable via the enterprise AllowSocketPoolSizeRandomizationForProxies policy, keeping the leak closed for ordinary users.

Changed Functions

FunctionChangeNotes
NetworkContextConfigurationManagedProxySettingsBrowserTest
chrome/browser/net/network_context_configuration_browsertest.cc
modified
if
chrome/browser/net/system_network_context_manager.cc
modified

Files Changed

  • chrome/browser/net/network_context_configuration_browsertest.cc
  • chrome/browser/net/system_network_context_manager.cc
  • chrome/browser/policy/configuration_policy_handler_list_factory.cc
  • chrome/common/pref_names.h
  • components/policy/resources/templates/policies.yaml
  • components/policy/resources/templates/policy_definitions/Miscellaneous/AllowSocketPoolSizeRandomizationForProxies.yaml
  • components/policy/resources/templates/policy_definitions/Miscellaneous/MaxConnectionsPerProxy.yaml
  • components/policy/resources/templates/policy_definitions/Miscellaneous/MaxConnectionsPerProxyForWebSocket.yaml
  • components/policy/resources/templates/policy_definitions/Miscellaneous/policy_atomic_groups.yaml

Audit Directions

  • Ungated security defaults
    Look for other xsleaks or side-channel defenses (e.g. randomized capacities, jittered timings) that are hardcoded on with no policy/pref gate, then verify disabling paths do not silently defeat the defense.
  • Feature-vs-policy precedence
    Audit spots where a base::Feature and an enterprise policy both influence one behavior, checking that policy correctly overrides the feature as intended in SetMaxConnectionsPerProxyChain-style plumbing.
  • Shared-pool capacity signals
    Review connection/socket pool limits reachable across sites or through proxies (kMaxConnectionsPerProxy, kMaxConnectionsPerProxyForWebSocket) for deterministic thresholds that expose measurable cross-site side channels.
From e904ef795270f669226db7cb5522d2973dceeb7c Mon Sep 17 00:00:00 2001
From: Ari Chivukula <[email protected]>
Date: Tue, 05 May 2026 15:28:17 -0700
Subject: [PATCH] [TCP] Add policy to gate proxy pool randomization

This allows enterprises to gate randomization of size for proxy pools
specifically. I don't see a reason to have a per-pool-type setting.

For context see:
https://xsleaks.dev/docs/defenses/secure-defaults/randomized-capacity/

Bug: 497837927
Change-Id: I2c45705ec42e25cb510cc1205faa85c7961ebd64
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7816739
Commit-Queue: Dominic Farolino <[email protected]>
Reviewed-by: Igor Ruvinov <[email protected]>
Auto-Submit: Ari Chivukula <[email protected]>
Reviewed-by: mmenke <[email protected]>
Reviewed-by: Dominic Farolino <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1625761}
---

diff --git a/chrome/browser/net/network_context_configuration_browsertest.cc b/chrome/browser/net/network_context_configuration_browsertest.cc
index 2bb49c3..33ecdd2 100644
--- a/chrome/browser/net/network_context_configuration_browsertest.cc
+++ b/chrome/browser/net/network_context_configuration_browsertest.cc
@@ -2097,7 +2097,12 @@
  public:
   const size_t kTestMaxConnectionsPerProxy = 16;
 
-  NetworkContextConfigurationManagedProxySettingsBrowserTest() = default;
+  NetworkContextConfigurationManagedProxySettingsBrowserTest() {
+    // The test still works as this is overridden by the policy
+    // kPermitSocketPoolSizeRandomizationForProxies below.
+    scoped_feature_list_.InitAndEnableFeature(
+        net::features::kTcpSocketPoolLimitRandomization);
+  }
 
   NetworkContextConfigurationManagedProxySettingsBrowserTest(
       const NetworkContextConfigurationManagedProxySettingsBrowserTest&) =
@@ -2123,6 +2128,10 @@
                  policy::POLICY_SOURCE_CLOUD,
                  base::Value(static_cast<int>(kTestMaxConnectionsPerProxy)),
                  /*external_data_fetcher=*/nullptr);
+    policies.Set(policy::key::kAllowSocketPoolSizeRandomizationForProxies,
+                 policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_MACHINE,
+                 policy::POLICY_SOURCE_CLOUD, base::Value(false),
+                 /*external_data_fetcher=*/nullptr);
     UpdateChromePolicy(policies);
   }
 
@@ -2133,6 +2142,9 @@
   size_t GetExpectedMaxConnectionsPerProxyForWebSocket() const override {
     return kTestMaxConnectionsPerProxy;
   }
+
+ private:
+  base::test::ScopedFeatureList scoped_feature_list_;
 };
 
 IN_PROC_BROWSER_TEST_P(
diff --git a/chrome/browser/net/system_network_context_manager.cc b/chrome/browser/net/system_network_context_manager.cc
index 089a007..c91cce0 100644
--- a/chrome/browser/net/system_network_context_manager.cc
+++ b/chrome/browser/net/system_network_context_manager.cc
@@ -760,6 +760,9 @@
 
   registry->RegisterIntegerPref(prefs::kMaxConnectionsPerProxyForWebSocket, -1);
 
+  registry->RegisterBooleanPref(
+      prefs::kAllowSocketPoolSizeRandomizationForProxies, true);
+
   registry->RegisterListPref(prefs::kExplicitlyAllowedNetworkPorts);
 
 #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX)
@@ -852,10 +855,10 @@
           ? std::optional<uint32_t>(
                 base::saturated_cast<uint32_t>(max_connections_websocket))
           : std::nullopt;
-  if (max_connections_normal_clamp || max_connections_websocket_clamp) {
-    network_service->SetMaxConnectionsPerProxyChain(
-        max_connections_normal_clamp, max_connections_websocket_clamp);
-  }
+  network_service->SetMaxConnectionsPerProxyChain(
+      max_connections_normal_clamp, max_connections_websocket_clamp,
+      local_state_->GetBoolean(
+          prefs::kAllowSocketPoolSizeRandomizationForProxies));
 
   network_service_network_context_.reset();
   content::CreateNetworkContextInNetworkService(
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
index ae5dbd5..772de728 100644
--- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc
+++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -486,6 +486,9 @@
   { key::kMaxConnectionsPerProxyForWebSocket,
     prefs::kMaxConnectionsPerProxyForWebSocket,
     base::Value::Type::INTEGER },
+  { key::kAllowSocketPoolSizeRandomizationForProxies,
+    prefs::kAllowSocketPoolSizeRandomizationForProxies,
+    base::Value::Type::BOOLEAN },
 // Policies for all platforms - End
 #if BUILDFLAG(IS_ANDROID)
   { key::kAccessibilityPerformanceFilteringAllowed,
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index f815914..ed07378 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -2490,6 +2490,8 @@
     "net.max_connections_per_proxy";
 inline constexpr char kMaxConnectionsPerProxyForWebSocket[] =
     "net.max_connections_per_proxy_for_websocket";
+inline constexpr char kAllowSocketPoolSizeRandomizationForProxies[] =
+    "net.allow_socket_pool_size_randomization_for_proxies";
 
 #if BUILDFLAG(IS_MAC)
 // A boolean that tracks whether to show a notification when trying to quit
diff --git a/components/policy/resources/templates/policies.yaml b/components/policy/resources/templates/policies.yaml
index 2d0c498d..e9a95403 100644
--- a/components/policy/resources/templates/policies.yaml
+++ b/components/policy/resources/templates/policies.yaml
@@ -1445,6 +1445,7 @@
   1444: DataUrlInWebWorkerOpaqueOriginEnabled
   1445: KioskPinchToZoomAllowed
   1446: SecuritySignalsClientCertificatesSelectors
+  1447: AllowSocketPoolSizeRandomizationForProxies
 
 atomic_groups:
   1: Homepage
diff --git a/components/policy/resources/templates/policy_definitions/Miscellaneous/AllowSocketPoolSizeRandomizationForProxies.yaml b/components/policy/resources/templates/policy_definitions/Miscellaneous/AllowSocketPoolSizeRandomizationForProxies.yaml
new file mode 100644
index 0000000..47fef96
--- /dev/null
+++ b/components/policy/resources/templates/policy_definitions/Miscellaneous/AllowSocketPoolSizeRandomizationForProxies.yaml
@@ -0,0 +1,31 @@
+caption: Allow socket pool size randomization for proxies
+default: true
+desc: |-
+  Socket pool size randomization is a security mechanism that prevents attackers from exploiting deterministic capacity limits to learn cross-site information.
+  If the capacity for a pool is normally 128 sockets, this mechanism randomly caps the pool between 128 and 256.
+  This can allow up to 2x as many connections to the proxy, but in practice the expected value is more like 1.2x.
+
+  This impacts the settings from <ph name="MAX_CONNECTIONS_PER_PROXY_POLICY_NAME">MaxConnectionsPerProxy</ph> and <ph name="MAX_CONNECTIONS_PER_PROXY_FOR_WEBSOCKET_POLICY_NAME">MaxConnectionsPerProxyForWebSocket</ph>.
+  Instead of them defining the upper limit, the upper limit is 2x their values (though again, the expected value in practice is more like 1.2x them).
+
+  This is enabled by default for all pools, but this policy allows the feature to be disabled for proxy pools specifically.
+example_value: true
+features:
+  dynamic_refresh: false
+  per_profile: false
+items:
+- caption: Allow socket pool randomization for proxies
+  value: true
+- caption: Prevent socket pool randomization for proxies
+  value: false
+owners:
+- file://components/policy/OWNERS
+- [email protected]
+schema:
+  type: boolean
+supported_on:
+- android:150-
+- chrome.*:150-
+- chrome_os:150-
+tags: []
+type: main
diff --git a/components/policy/resources/templates/policy_definitions/Miscellaneous/MaxConnectionsPerProxy.yaml b/components/policy/resources/templates/policy_definitions/Miscellaneous/MaxConnectionsPerProxy.yaml
index 7a5d4af..5175327 100644
--- a/components/policy/resources/templates/policy_definitions/Miscellaneous/MaxConnectionsPerProxy.yaml
+++ b/components/policy/resources/templates/policy_definitions/Miscellaneous/MaxConnectionsPerProxy.yaml
@@ -17,6 +17,8 @@
   The value should be equal to or lower than 256 (99 in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> 147 and earlier).
   Setting a value above that limit will cause 256 (99 in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> 147 and earlier) to be used.
   Raise above the default (128) at your own risk.
+
+  Please note that the enforced limits are impacted by <ph name="ALLOW_SOCKET_POOL_SIZE_RANDOMIZATION_FOR_PROXIES_POLICY_NAME">AllowSocketPoolSizeRandomizationForProxies</ph>.
 example_value: 128
 features:
   dynamic_refresh: false
diff --git a/components/policy/resources/templates/policy_definitions/Miscellaneous/MaxConnectionsPerProxyForWebSocket.yaml b/components/policy/resources/templates/policy_definitions/Miscellaneous/MaxConnectionsPerProxyForWebSocket.yaml
index 784926d9..8365cd5 100644
--- a/components/policy/resources/templates/policy_definitions/Miscellaneous/MaxConnectionsPerProxyForWebSocket.yaml
+++ b/components/policy/resources/templates/policy_definitions/Miscellaneous/MaxConnectionsPerProxyForWebSocket.yaml
@@ -17,6 +17,8 @@
   The value should be equal to or lower than 256.
   Setting a value above that limit will cause 256 to be used.
   Raise above the default (128) at your own risk.
+
+  Please note that the enforced limits are impacted by <ph name="ALLOW_SOCKET_POOL_SIZE_RANDOMIZATION_FOR_PROXIES_POLICY_NAME">AllowSocketPoolSizeRandomizationForProxies</ph>.
 example_value: 128
 features:
   dynamic_refresh: false
diff --git a/components/policy/resources/templates/policy_definitions/Miscellaneous/policy_atomic_groups.yaml b/components/policy/resources/templates/policy_definitions/Miscellaneous/policy_atomic_groups.yaml
index fb41ff4..10190d7 100644
--- a/components/policy/resources/templates/policy_definitions/Miscellaneous/policy_atomic_groups.yaml
+++ b/components/policy/resources/templates/policy_definitions/Miscellaneous/policy_atomic_groups.yaml
@@ -3,3 +3,4 @@
   policies:
   - MaxConnectionsPerProxy
   - MaxConnectionsPerProxyForWebSocket
Loading diff…

Regression Test / PoC

shipped with the fix
diff --git a/chrome/browser/net/network_context_configuration_browsertest.cc b/chrome/browser/net/network_context_configuration_browsertest.cc
index 2bb49c3..33ecdd2 100644
--- a/chrome/browser/net/network_context_configuration_browsertest.cc
+++ b/chrome/browser/net/network_context_configuration_browsertest.cc
@@ -2097,7 +2097,12 @@
  public:
   const size_t kTestMaxConnectionsPerProxy = 16;
 
-  NetworkContextConfigurationManagedProxySettingsBrowserTest() = default;
+  NetworkContextConfigurationManagedProxySettingsBrowserTest() {
+    // The test still works as this is overridden by the policy
+    // kPermitSocketPoolSizeRandomizationForProxies below.
+    scoped_feature_list_.InitAndEnableFeature(
+        net::features::kTcpSocketPoolLimitRandomization);
+  }
 
   NetworkContextConfigurationManagedProxySettingsBrowserTest(
       const NetworkContextConfigurationManagedProxySettingsBrowserTest&) =
@@ -2123,6 +2128,10 @@
                  policy::POLICY_SOURCE_CLOUD,
                  base::Value(static_cast<int>(kTestMaxConnectionsPerProxy)),
                  /*external_data_fetcher=*/nullptr);
+    policies.Set(policy::key::kAllowSocketPoolSizeRandomizationForProxies,
+                 policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_MACHINE,
+                 policy::POLICY_SOURCE_CLOUD, base::Value(false),
+                 /*external_data_fetcher=*/nullptr);
     UpdateChromePolicy(policies);
   }
 
@@ -2133,6 +2142,9 @@
   size_t GetExpectedMaxConnectionsPerProxyForWebSocket() const override {
     return kTestMaxConnectionsPerProxy;
   }
+
+ private:
+  base::test::ScopedFeatureList scoped_feature_list_;
 };
 
 IN_PROC_BROWSER_TEST_P(
diff --git a/components/policy/test/data/pref_mapping/AllowSocketPoolSizeRandomizationForProxies.json b/components/policy/test/data/pref_mapping/AllowSocketPoolSizeRandomizationForProxies.json
new file mode 100644
index 0000000..8879fb8
--- /dev/null
+++ b/components/policy/test/data/pref_mapping/AllowSocketPoolSizeRandomizationForProxies.json
@@ -0,0 +1,20 @@
+[
+  {
+    "os": [
+      "chromeos",
+      "win",
+      "linux",
+      "mac",
+      "android"
+    ],
+    "simple_policy_pref_mapping_test": {
+      "default_value": true,
+      "pref_location":  "local_state",
+      "pref_name": "net.allow_socket_pool_size_randomization_for_proxies",
+      "values_to_test": [
+        true,
+        false
+      ]
+    }
+  }
+]
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc
index 4695b4db..5b1413cc 100644
--- a/net/http/http_network_transaction_unittest.cc
+++ b/net/http/http_network_transaction_unittest.cc
@@ -28434,39 +28434,50 @@
   SocketPoolAdditionalCapacity real_poll_128 =
       SocketPoolAdditionalCapacity::CreateForTest(
           /*base=*/0.1, /*capacity=*/128, /*minimum=*/0.3, /*noise=*/0.4);
-  for (bool proxy_pool_randomization : {true, false}) {
-    base::test::ScopedFeatureList feature_list;
-    feature_list.InitWithFeatureState(
-        features::kTcpSocketPoolLimitRandomizationForProxy,
-        proxy_pool_randomization);
-    std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
-    EXPECT_EQ(session
-                  ->GetSocketPool(HttpNetworkSession::SocketPoolType::kNormal,
-                                  ProxyChain::Direct())
-                  ->AdditionalCapacityForTest(),
-              real_poll_256);
-    EXPECT_EQ(
-        session
-            ->GetSocketPool(HttpNetworkSession::SocketPoolType::kWebSocket,
-                            ProxyChain::Direct())
-            ->AdditionalCapacityForTest(),
-        real_poll_256);
-    EXPECT_EQ(session
-                  ->GetSocketPool(
-                      HttpNetworkSession::SocketPoolType::kNormal,
-                      ProxyChain(ProxyServer::SCHEME_HTTPS,
-                                 SameProxyWithDifferentSchemesProxyResolver::
-                                     ProxyHostPortPair()))
-                  ->AdditionalCapacityForTest(),
-              proxy_pool_randomization ? real_poll_128 : empty_pool);
-    EXPECT_EQ(session
-                  ->GetSocketPool(
-                      HttpNetworkSession::SocketPoolType::kWebSocket,
-                      ProxyChain(ProxyServer::SCHEME_HTTPS,
-                                 SameProxyWithDifferentSchemesProxyResolver::
-                                     ProxyHostPortPair()))
-                  ->AdditionalCapacityForTest(),
-              proxy_pool_randomization ? real_poll_128 : empty_pool);
+  for (bool allow_proxy_pool_randomization : {true, false}) {
+    ClientSocketPoolManager::set_allow_size_randomization_for_proxy(
+        allow_proxy_pool_randomization);
+    for (bool proxy_pool_randomization_feature : {true, false}) {
+      base::test::ScopedFeatureList feature_list;
+      feature_list.InitWithFeatureState(
+          features::kTcpSocketPoolLimitRandomizationForProxy,
+          proxy_pool_randomization_feature);
+      std::unique_ptr<HttpNetworkSession> session =
+          CreateSession(&session_deps_);
+      EXPECT_EQ(session
+                    ->GetSocketPool(HttpNetworkSession::SocketPoolType::kNormal,
+                                    ProxyChain::Direct())
+                    ->AdditionalCapacityForTest(),
+                real_poll_256);
+      EXPECT_EQ(
+          session
+              ->GetSocketPool(HttpNetworkSession::SocketPoolType::kWebSocket,
+                              ProxyChain::Direct())
+              ->AdditionalCapacityForTest(),
+          real_poll_256);
+      EXPECT_EQ(
+          session
+              ->GetSocketPool(
+                  HttpNetworkSession::SocketPoolType::kNormal,
+                  ProxyChain(ProxyServer::SCHEME_HTTPS,
+                             SameProxyWithDifferentSchemesProxyResolver::
+                                 ProxyHostPortPair()))
+              ->AdditionalCapacityForTest(),
+          allow_proxy_pool_randomization && proxy_pool_randomization_feature
+              ? real_poll_128
+              : empty_pool);
+      EXPECT_EQ(
+          session
+              ->GetSocketPool(
+                  HttpNetworkSession::SocketPoolType::kWebSocket,
+                  ProxyChain(ProxyServer::SCHEME_HTTPS,
+                             SameProxyWithDifferentSchemesProxyResolver::
+                                 ProxyHostPortPair()))
+              ->AdditionalCapacityForTest(),
+          allow_proxy_pool_randomization && proxy_pool_randomization_feature
+              ? real_poll_128
+              : empty_pool);
+    }
   }
 }
diff --git a/services/network/network_service_unittest.cc b/services/network/network_service_unittest.cc
index f5454563..a915e189 100644
--- a/services/network/network_service_unittest.cc
+++ b/services/network/network_service_unittest.cc
@@ -1212,6 +1212,10 @@
       net::HttpNetworkSession::SocketPoolType::kWebSocket);
 }
 
+static bool GetGlobalAllowSizeRandomizationForProxy() {
+  return net::ClientSocketPoolManager::allow_size_randomization_for_proxy();
+}
+
 // Tests that NetworkService::SetMaxConnectionsPerProxyChain() (1) modifies
 // globals in net::ClientSocketPoolManager (2) saturates out of bound values.
 TEST_F(NetworkServiceTest, SetMaxConnectionsPerProxyChain) {
@@ -1222,44 +1226,52 @@
   // Starts off at default value.
   EXPECT_EQ(kDefault, GetGlobalMaxConnectionsPerProxyChain());
   EXPECT_EQ(kDefault, GetGlobalMaxConnectionsPerProxyChainForWebSocket());
+  EXPECT_EQ(true, GetGlobalAllowSizeRandomizationForProxy());
 
   // Anything less than kMin saturates to kMin.
-  service()->SetMaxConnectionsPerProxyChain(kMin - 1, kMin - 1);
+  service()->SetMaxConnectionsPerProxyChain(kMin - 1, kMin - 1, false);
   EXPECT_EQ(kMin, GetGlobalMaxConnectionsPerProxyChain());
   EXPECT_EQ(kMin, GetGlobalMaxConnectionsPerProxyChainForWebSocket());
+  EXPECT_EQ(false, GetGlobalAllowSizeRandomizationForProxy());
 
   // Anything larger than kMax saturates to kMax
-  service()->SetMaxConnectionsPerProxyChain(kMax + 1, kMax + 1);
+  service()->SetMaxConnectionsPerProxyChain(kMax + 1, kMax + 1, true);
   EXPECT_EQ(kMax, GetGlobalMaxConnectionsPerProxyChain());
   EXPECT_EQ(kMax, GetGlobalMaxConnectionsPerProxyChainForWebSocket());
+  EXPECT_EQ(true, GetGlobalAllowSizeRandomizationForProxy());
 
   // Anything in between kMin and kMax should be set exactly.
-  service()->SetMaxConnectionsPerProxyChain(58, 58);
+  service()->SetMaxConnectionsPerProxyChain(58, 58, false);
   EXPECT_EQ(58u, GetGlobalMaxConnectionsPerProxyChain());
   EXPECT_EQ(58u, GetGlobalMaxConnectionsPerProxyChainForWebSocket());
+  EXPECT_EQ(false, GetGlobalAllowSizeRandomizationForProxy());
 
   // It's possible to update neither if that's you're thing.
-  service()->SetMaxConnectionsPerProxyChain(std::nullopt, std::nullopt);
+  service()->SetMaxConnectionsPerProxyChain(std::nullopt, std::nullopt, true);
   EXPECT_EQ(58u, GetGlobalMaxConnectionsPerProxyChain());
   EXPECT_EQ(58u, GetGlobalMaxConnectionsPerProxyChainForWebSocket());
+  EXPECT_EQ(true, GetGlobalAllowSizeRandomizationForProxy());
 
   // It's possible to update just one or the other.
-  service()->SetMaxConnectionsPerProxyChain(56, std::nullopt);
+  service()->SetMaxConnectionsPerProxyChain(56, std::nullopt, false);
   EXPECT_EQ(56u, GetGlobalMaxConnectionsPerProxyChain());
   EXPECT_EQ(58u, GetGlobalMaxConnectionsPerProxyChainForWebSocket());
+  EXPECT_EQ(false, GetGlobalAllowSizeRandomizationForProxy());
 
   // It's possible to update just one or the other.
-  service()->SetMaxConnectionsPerProxyChain(std::nullopt, 60);
+  service()->SetMaxConnectionsPerProxyChain(std::nullopt, 60, true);
   EXPECT_EQ(56u, GetGlobalMaxConnectionsPerProxyChain());
   EXPECT_EQ(60u, GetGlobalMaxConnectionsPerProxyChainForWebSocket());
+  EXPECT_EQ(true, GetGlobalAllowSizeRandomizationForProxy());
 
   // It's possible to update both to different values.
-  service()->SetMaxConnectionsPerProxyChain(57, 59);
+  service()->SetMaxConnectionsPerProxyChain(57, 59, false);
   EXPECT_EQ(57u, GetGlobalMaxConnectionsPerProxyChain());
   EXPECT_EQ(59u, GetGlobalMaxConnectionsPerProxyChainForWebSocket());
+  EXPECT_EQ(false, GetGlobalAllowSizeRandomizationForProxy());
 
   // Restore the default value to minize sideffects.
-  service()->SetMaxConnectionsPerProxyChain(kDefault, kDefault);
+  service()->SetMaxConnectionsPerProxyChain(kDefault, kDefault, true);
 }
 
 #if BUILDFLAG(IS_CT_SUPPORTED)
Loading diff…

Original Bug Report

The reporter's bug is still restricted on the tracker. Chrome de-restricts security bugs ~30–90 days after the fix ships; a later run will backfill it here.