From d01b461f71e255dcb5d7d0ee84a560f26cfe0b6f Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 25 May 2026 18:36:39 +0200 Subject: [PATCH] net: ensure no direct private broadcast connections Private broadcast connections use either Tor or I2P, which require a proxy intrinsically or IPv4 or IPv6 which must use a proxy in the context of private broadcast to avoid leaking the originator's IP address. Add a safety check to guard against future mistakes. Co-authored-by: Andrew Toth --- src/net.cpp | 7 +++++-- src/test/fuzz/connman.cpp | 8 +++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index 7edb8eacf49..3e2b81b09aa 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -488,8 +488,11 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, LogDebug(BCLog::PROXY, "Using proxy: %s to connect to %s\n", use_proxy->ToString(), target_addr.ToStringAddrPort()); sock = ConnectThroughProxy(*use_proxy, target_addr.ToStringAddr(), target_addr.GetPort(), proxyConnectionFailed); } else { - // no proxy needed (none set for target network) - sock = ConnectDirectly(target_addr, conn_type == ConnectionType::MANUAL); + // No proxy needed (none set for target network). Private broadcast connections + // must always use a proxy, otherwise they would leak the originator's IP address. + if (Assume(conn_type != ConnectionType::PRIVATE_BROADCAST)) { + sock = ConnectDirectly(target_addr, conn_type == ConnectionType::MANUAL); + } } if (!proxyConnectionFailed) { // If a connection to the node was attempted, and failure (if any) is not caused by a problem connecting to diff --git a/src/test/fuzz/connman.cpp b/src/test/fuzz/connman.cpp index 1b0859d6ffe..55b5800c63e 100644 --- a/src/test/fuzz/connman.cpp +++ b/src/test/fuzz/connman.cpp @@ -188,13 +188,19 @@ FUZZ_TARGET(connman, .init = initialize_connman) conn_type = ConnectionType::OUTBOUND_FULL_RELAY; } + std::optional proxy_override; + if (conn_type == ConnectionType::PRIVATE_BROADCAST || fuzzed_data_provider.ConsumeBool()) { + proxy_override.emplace(ConsumeService(fuzzed_data_provider)); + } + connman.OpenNetworkConnection( /*addrConnect=*/random_address, /*fCountFailure=*/fuzzed_data_provider.ConsumeBool(), /*grant_outbound=*/{}, /*pszDest=*/fuzzed_data_provider.ConsumeBool() ? nullptr : random_string.c_str(), /*conn_type=*/conn_type, - /*use_v2transport=*/fuzzed_data_provider.ConsumeBool()); + /*use_v2transport=*/fuzzed_data_provider.ConsumeBool(), + /*proxy_override=*/proxy_override); }, [&] { connman.SetNetworkActive(fuzzed_data_provider.ConsumeBool());