wallet: rpc; req. ssl cert params w/ proxy when daemon not onion/i2p
What changed, and why it matters
This change tightens security for Monero wallet users who connect to a daemon through a proxy (such as Tor or I2P). Previously, when a proxy was used, the wallet did not require users to supply a way to verify the daemon's SSL certificate. That could let a malicious exit node or proxy operator impersonate the daemon and steal wallet data or funds. The patch now requires strong verification (a known certificate, fingerprint, or an onion/i2p address) whenever a proxy or SSL is used.
Users and integrators running wallet RPC with proxies should upgrade and ensure they configure ssl_ca_file, ssl_allowed_fingerprints, ssl_allow_any_cert, or use a .onion/.i2p daemon address. Review any existing set_daemon calls that pass a proxy without verification settings.
Security signals we found
MITM protection gap closed for proxy connections
SSL/TLS verification now enforced when proxy is configured
Host-aware certificate/fingerprint verification
Error message updated to mention proxy and strong verification options
Evidence from the diff
The patch modifies wallet_rpc_server.cpp’s set_daemon RPC handler. It changes the condition that decides whether strong SSL/TLS verification is mandatory. Before, verification was required only when SSL was explicitly enabled. Now it is also required when a proxy is configured (use_proxy). It also extracts the real daemon host (stripping the port) and passes it to has_strong_verification instead of an empty string_ref, so verification is checked against the actual destination. The error message is updated accordingly. This is a defensive hardening fix, not a vulnerability patch for a specific CVE, but it closes a gap where proxy+plain-SSL connections could be downgraded or MITM’d.
Changed components
src/wallet/wallet_rpc_server.cppwallet RPC set_daemon endpointSSL/proxy daemon connection logicInspect captured patch +6 / −3
diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp
index 2dae20f..61f3e3f 100644
--- a/src/wallet/wallet_rpc_server.cpp
+++ b/src/wallet/wallet_rpc_server.cpp
@@ -4827,14 +4827,17 @@ namespace tools
std::move(req.ssl_private_key_path), std::move(req.ssl_certificate_path)
};
+ // If a proxy or SSL is explicitly enabled, then ssl_allow_any_cert, ssl_ca_file, ssl_allowed_fingerprints, or use of a .onion or .i2p address is required
+ const boost::string_ref real_daemon = boost::string_ref{req.address}.substr(0, req.address.rfind(':'));
+ const bool use_proxy = !req.proxy.empty();
const bool verification_required =
ssl_options.verification != epee::net_utils::ssl_verification_t::none &&
- ssl_options.support == epee::net_utils::ssl_support_t::e_ssl_support_enabled;
+ (ssl_options.support == epee::net_utils::ssl_support_t::e_ssl_support_enabled || use_proxy);
- if (verification_required && !ssl_options.has_strong_verification(boost::string_ref{}))
+ if (verification_required && !ssl_options.has_strong_verification(real_daemon))
{
er.code = WALLET_RPC_ERROR_CODE_NO_DAEMON_CONNECTION;
- er.message = "SSL is enabled but no user certificate or fingerprints were provided";
+ er.message = "SSL or proxy is enabled but no strong verification was configured; set ssl_allow_any_cert, ssl_ca_file, or ssl_allowed_fingerprints, or use a .onion or .i2p address";
return false;
}
Why this scored 63/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.